mIRC Home    About    Download    Register    News    Help

Print Thread
#235446 18/12/11 09:32 PM
Joined: Feb 2010
Posts: 4
S
Self-satisified door
OP Offline
Self-satisified door
S
Joined: Feb 2010
Posts: 4
Hi I need an identifier to return the name of the Nth alias in the specified file, and where N=0 returns the number of aliases in that file.

I know about $isalias so I can check to see if a specified alias exists and then check to see if it's in a specific file, but my idea is for an overhaul of my acromancer script, to be able to create each style as an alias in a specific file. Easy enough, but when it comes to presenting a list of available styles to the user to choose from for each word in the list, I need to be able to scan for available styles to list them dynamically.

Ex1. $aliasname(aliases.ini,0) == 12 ;there are 12 aliases in aliases.ini
Ex2. $aliasname(aliases.ini,1) == j ;the first alias in aliases.ini is 'j'
Ex3. $aliasname(aliases.ini,2) == join ;the second alias in aliases.ini is 'join'
etc.

Joined: Nov 2009
Posts: 295
P
Fjord artisan
Offline
Fjord artisan
P
Joined: Nov 2009
Posts: 295
Well I made this little alias to do what you want.

Assumptions/behavior:
if file doesn't exist returns 0
if there are 4 aliases and you ask for 5 it will return 0
assumes aliases are formatted like "alias aliasname " in the script file

Code:
alias aliasname {
  if ($isfile($1)) && ($2 isnum 0-) {
    set -l %num 0
    while ($read($qt($1),r,^alias(\x20-l|) (.*?)\x20,$calc($readn + 1))) { set -l %a $addtok(%a,$regml(2),32) | inc %num }
    if ($2 == 0) return %num
    elseif ($2 isnum 1-) return $iif($gettok(%a,$2,32),$v1,0)
  }
  else return 0
}
;updated to work with alias -l, forget about that at first


Hope it works for you, it was fun to make

I based this off of the format that aliases use in normal script files, if you are using an alias script file or an ini based script file let me know and I can change it work with the other formats.

Last edited by pball; 18/12/11 10:46 PM.

http://scripting.pball.win
My personal site with some scripts I've released.
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Judging by the OP's use of the filename "aliases.ini", I think he is looking to have this work on ini files and alias files. Your identifier seems to work with neither.

As a sidenote, the convention is to return $null if the index value is out of range or if there is any other error. "0" is a valid alias name, so it's ambiguous to return that in an error situation.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
This supports .ini files and alias files, in addition to remote scripts. Note that the alias cannot detect remote scripts from alias files, so it will still detect "/op /mode # +o $1" as an alias if it was placed at the beginning of the line in a remote script, which mIRC wouldn't recognize. You could add another switch to the identifier to denote whether the file was a remote/aliases file, or you could just handle this case in another way.

Code:
alias aliasname {
  var %file = $1, %index = $2, %w = @__aliasname
  var %match = /^ $+ $iif(*.ini iswm %file,(?:n\d+=),) $+ $&
    (?:alias\s+(?:-l\s+)?)?\/?([^\{ \[#;]+).*$/
  if (!$exists(%file)) return $null
  if ($window(%w)) clear %w
  window -h %w
  filter -gfw %file %w %match
  var %value = $line(%w,%index)
  if (%index != 0) %value = $regsubex(%value,%match,\1)
  window -c %w
  return %value
}


I should point out that this script relies on proper indenting from the script editor. If you edit your scripts in another file, make sure to hit Ctrl+H in the script editor to properly indent the file.

Note: From the sound of it, it seems like your goal here is to loop over the aliases. If you plan on looping over all $aliasname(file,N) (where N=1..total), it would be much more efficient to create your own custom version of this that uses /filter -k instead of filtering to a separate window. It would look like this:

Code:
; Usage: /aliasname_loop <filename> <command>
alias aliasname_loop {
  set -u0 %aliasname.file $1
  set -u0 %aliasname.callback $2-
  set -u0 %aliasname.num 0
  set -u0 %aliasname.match /^ $+ $iif(*.ini iswm %aliasname.file,(?:n\d+=),) $+ $&
    (?:alias\s+(?:-l\s+)?)?\/?([^\{ \[#;]+).*$/
  if (!$exists(%aliasname.file)) return $null
  filter -fk %aliasname.file aliasname_filter *
  unset %aliasname.*
}
alias aliasname_filter {
  if ($regex($1-,%aliasname.match)) {
    inc %aliasname.num
    %aliasname.callback %aliasname.num $regml(1)
  }
}


Calling "/aliasname_loop aliases.ini /echo -a" would /echo -a each resulting alias where $1 = the index and $2 = the alias name. You could make the command a custom alias that processes each result.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
$exists checks for the presence of a directory or a file, so your script would attempt to run if there was a directory called "aliases.ini" which is of course a valid name.

I haven't tried it to see if that would make mIRC throw out an error but I guess it would when it tries to use /filter. You should use $isfile.

Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Note that $isfile still isn't enough to guarantee that /filter will succeed, since the file can be unreadable for other reasons (locked, perms, etc.). The $exists check is just sanity checking, you should probably be doing your own checks to make sure you're actually picking a path which is a readable file.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Jul 2006
Posts: 4,144
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,144
\s is matching more than a space, matching more than a space here is wrong, it matches for example
Code:
alias
alias_name {


#mircscripting @ irc.swiftirc.net == the best mIRC help channel
Joined: Nov 2008
Posts: 22
F
Ameglian cow
Offline
Ameglian cow
F
Joined: Nov 2008
Posts: 22
Originally Posted By: Wims
\s is matching more than a space, matching more than a space here is wrong, it matches for example
Code:
alias
alias_name {


It's not that the \s is matching more than a space, it's that the pattern is not ensuring a space is between the alias [-l] and the name. Changing the pattern (on the second part of it) to something like below would work.:

Code:
(?:alias\s+(?:-l\s+)?)?\s\/?([^\{ \[#;]+).*$/



Last edited by Firstmate; 26/12/11 07:08 PM.
Joined: Jul 2006
Posts: 4,144
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,144
Quote:
It's not that the \s is matching more than a space
Yes it is, \s in pcre match the ascii values 9, 10, 12, 13 and 32.
Quote:
it's that the pattern is not ensuring a space is between the alias [-l] and the name.
Apart from the \s problem, it is, adding one more space (and not one more \s) is rather wrong if we consider that the original intention was to match indented code (and then that the + on \s+ is here as a convenience/security)


#mircscripting @ irc.swiftirc.net == the best mIRC help channel
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Originally Posted By: Wims
Yes it is, \s in pcre match the ascii values 9, 10, 12, 13 and 32.


Yes, but since /filter returns only a single line at a time, it can never match 10 or 13, therefore your example of "alias\nalias_test" will never match. Please test your statements before making them.

Originally Posted By: Wims
is rather wrong if we consider that the original intention was to match indented code


Indentation never uses tabs, so if the code is correctly formatted it will work fine. I don't write code with the assumption of bad input. That's an exercise I leave up to users.

In general, I think you're blowing the "wrongness" out of proportion, but feel free to fix it rather than complain. You could easily replace \s with " ". I've had no problems using it with any of my scripts, so it can't be that wrong.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Jul 2006
Posts: 4,144
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,144
Yeah sorry, the exemple is a bad one, but it shows potential problems, I didn't have /filter in mind, it was just a little note because using a space is better if you know you have to match a space.


#mircscripting @ irc.swiftirc.net == the best mIRC help channel
Joined: Nov 2008
Posts: 22
F
Ameglian cow
Offline
Ameglian cow
F
Joined: Nov 2008
Posts: 22
Originally Posted By: argv0
Originally Posted By: Wims
Yes it is, \s in pcre match the ascii values 9, 10, 12, 13 and 32.


Yes, but since /filter returns only a single line at a time, it can never match 10 or 13, therefore your example of "alias\nalias_test" will never match. Please test your statements before making them.

Originally Posted By: Wims
is rather wrong if we consider that the original intention was to match indented code


Indentation never uses tabs, so if the code is correctly formatted it will work fine. I don't write code with the assumption of bad input. That's an exercise I leave up to users.

In general, I think you're blowing the "wrongness" out of proportion, but feel free to fix it rather than complain. You could easily replace \s with " ". I've had no problems using it with any of my scripts, so it can't be that wrong.


I think wims was listing cases where your pattern is false.
Just as a test-case, we'll use this as the pattern (in other words, ignoring if it came from a .ini):
Code:
/^(?:alias\s+(?:-l\s+)?)?\/?([^\{ \[#;]+).*$/


Just type this into your mIRC:
Code:
//echo -a $regex(alias,/^(?:alias\s+(?:-l\s+)?)?\/?([^\{ \[#;]+).*$/)
//echo -a $regex(alias_test,/^(?:alias\s+(?:-l\s+)?)?\/?([^\{ \[#;]+).*$/)


Both regex patterns will match.

Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
There's nothing wrong with those lines individually, Wims was pointing out that, separated across multiple lines, "alias\nalias_test" would match incorrectly. However this is not the case. The test cases you gave match properly.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Nov 2008
Posts: 22
F
Ameglian cow
Offline
Ameglian cow
F
Joined: Nov 2008
Posts: 22
My bad, I was thinking something different.

Joined: Nov 2009
Posts: 295
P
Fjord artisan
Offline
Fjord artisan
P
Joined: Nov 2009
Posts: 295
Originally Posted By: argv0
Indentation never uses tabs, so if the code is correctly formatted it will work fine. I don't write code with the assumption of bad input. That's an exercise I leave up to users.


I don't think you should ever write code without assuming for bad input, especially if it's not for yourself. I don't always go over board but I'd make a few scripts that are nearly idiot proof and some times you need to do that.


http://scripting.pball.win
My personal site with some scripts I've released.
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Our opinions differ here. I only sanity check when the input could be exploited in some malicious way or severely break the internal logic of my script. In this case, neither scenario can occur-- the worst case is you get some invalid script lines detected as aliases. I write my scripts using DbC, and, in most cases, the pre-condition for all my scripts is "well formed input". As I said, better error checking can be an exercise left to the users of this script.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Feb 2010
Posts: 4
S
Self-satisified door
OP Offline
Self-satisified door
S
Joined: Feb 2010
Posts: 4
Thanks a lot guys smile

I've not had chance to try these out as I've kinda stepped away from mIRC and computers in general now due to personal reasons, and I'd not received e-mails to say I'd had replies therefore completely forgot about the thread.

I will point out, that for what I wanted to do, the alias file (an .ini file loaded in the Aliases tab of Scripts Editor) would always be something along the lines of acromancer-styles.ini and $aliasname would indeed be used in a loop to grab each and every alias name (which would be listed in a 'Styles' combo box for the end user to choose the desired output style for their acro's).

I hope this will come in handy for somebody else at a later date.


Link Copied to Clipboard