Issue about comma separated list in Macro

All about the macro plugin can be found in this forum. This forum is intended for the macro plugin only.

Moderator: Moderators

Dark Airnel
Been there done that!
Been there done that!
Posts: 133
Joined: 09 Oct 2009, 01:43
Noob?: No

Issue about comma separated list in Macro

#1 Post by Dark Airnel »

Hi I noticed this behavior in macro:

Code: Select all

macro listtest {
[
  $list = Cold Medicine, Apple, Strawberry, Grape
  :check
  $var = [$list]
  if ($var == "") goto end
  log The first element of \$list is $var
  log Now \$list contains $list
  #Check if we have any of the items in the list in inventory
  $invItem = @invamount ($var)
  log You have $invItem $var in inventory
  goto check
  :end
  log end of list
]
}
Result:
macro listtest
[macro log] The first element of \$list is Cold Medicine
[macro log] Now \$list contains Apple, Strawberry, Grape
[macro log] You have 25 Cold Medicine in inventory
[macro log] The first element of \$list is Apple
[macro log] Now \$list contains Strawberry, Grape
[macro log] You have 0 Apple in inventory
[macro log] The first element of \$list is Strawberry
[macro log] Now \$list contains Grape
[macro log] You have 0 Strawberry in inventory
[macro log] The first element of \$list is Grape
[macro log] Now \$list contains
[macro log] You have 0 Grape in inventory
[macro log] end of list

Please notice that I was able to check the quantity of Cold Medicine when it is on the start of the list however:

Code: Select all

macro listtest {
[
  $list = Banana, Cold Medicine, Apple, Strawberry, Grape
  :check
  $var = [$list]
  if ($var == "") goto end
  log The first element of \$list is $var
  log Now \$list contains $list
  #Check if we have any of the items in the list in inventory
  $invItem = @invamount ($var)
  log You have $invItem $var in inventory
  goto check
  :end
  log end of list
]
}
Result:

macro listtest
[macro log] The first element of \$list is Banana
[macro log] Now \$list contains Cold Medicine, Apple, Strawberry, Grape
[macro log] You have 0 Banana in inventory
[macro log] The first element of \$list is Cold Medicine
[macro log] Now \$list contains Apple, Strawberry, Grape
[macro log] You have 0 Cold Medicine in inventory
[macro log] The first element of \$list is Apple
[macro log] Now \$list contains Strawberry, Grape
[macro log] You have 0 Apple in inventory
[macro log] The first element of \$list is Strawberry
[macro log] Now \$list contains Grape
[macro log] You have 0 Strawberry in inventory
[macro log] The first element of \$list is Grape
[macro log] Now \$list contains
[macro log] You have 0 Grape in inventory
[macro log] end of list

It seems that any item which is not at the start of the list has a trailing space (" Cold Medicine") that's why it gives a 0 value when the quantity is check using the @invamount (item) feature. Is this an intended behavior of macro or a bug? In order to counter this, I have to write a comma separated list this way:

$item = item1,item2,item3,item4,item5

instead of this way:
$item = item1, item2, item3, item4, item5

Problems occur though if the list comes from a standard output such as $.status

example:

if (Headache ~ $.status) goto drinkmedicine

The code will not be able to check that the character has a headache unless Headache happens to be at the start of the list because by default, $.status produces list with comma and spaces (Fever, Headache, etc)
Dark Airnel
Been there done that!
Been there done that!
Posts: 133
Joined: 09 Oct 2009, 01:43
Noob?: No

Re: Issue about comma separated list in Macro

#2 Post by Dark Airnel »

I got the culprit: foreach my $e (split(/,/, $b)) {return 1 if $a eq lc($e)}

Here's the code in Utilities.pm

Code: Select all

sub cmpr {
	my ($a, $cond, $b) = @_;
	unless (defined $a && defined $cond && defined $b) {
		# this produces a warning but that's what we want
		error "cmpr: wrong # of arguments ($a) ($cond) ($b)\n", "macro";
		return 0
	}

	if ($a =~ /^\s*(-?[\d.]+)\s*\.{2}\s*(-?[\d.]+)\s*$/) {
		my ($a1, $a2) = ($1, $2);
		if ($b =~ /^-?[\d.]+$/) {
			if ($cond eq "!=") {return (between($a1, $b, $a2))?0:1}
			if ($cond eq "=" || $cond eq "==" || $cond eq "=~" || $cond eq "~") {
				return between($a1, $b, $a2)
			}
		}
		error "cmpr: wrong # of arguments ($a) ($cond) ($b)\n--> ($b) <-- maybe should be numeric?\n", "macro";
		return 0
	}

	if ($b =~ /^\s*(-?[\d.]+)\s*\.{2}\s*(-?[\d.]+)\s*$/) {
		my ($b1, $b2) = ($1, $2);
		if ($a =~ /^-?[\d.]+$/) {
			if ($cond eq "!=") {return (between($b1, $a, $b2))?0:1}
			if ($cond eq "=" || $cond eq "==" || $cond eq "=~" || $cond eq "~") {
				return between($b1, $a, $b2)
			}
		}
		error "cmpr: wrong # of arguments ($a) ($cond) ($b)\n--> ($a) <-- maybe should be numeric?\n", "macro";
		return 0
	}

	if ($a =~ /^-?[\d.]+$/ && $b =~ /^-?[\d.]+$/) {
		if (($cond eq "=" || $cond eq "==") && $a == $b) {return 1}
		if ($cond eq ">=" && $a >= $b) {return 1}
		if ($cond eq "<=" && $a <= $b) {return 1}
		if ($cond eq ">"  && $a > $b)  {return 1}
		if ($cond eq "<"  && $a < $b)  {return 1}
		if ($cond eq "!=" && $a != $b) {return 1}
		return 0
	}

	if (($cond eq "=" || $cond eq "==") && $a eq $b) {return 1}
	if ($cond eq "!=" && $a ne $b) {return 1}
	if ($cond eq "~") {
		$a = lc($a);
		#original: foreach my $e (split(/,/, $b)) {return 1 if $a eq lc($e)}
		foreach my $e (split(/,\s*/, $b)) {return 1 if $a eq lc($e)}
	}
	if ($cond eq "=~" && $b =~ /^\/.*?\/\w?\s*$/) {
		return match($a, $b, 1)
	}

	return 0
}