nesdev.com
http://forums.nesdev.com/

Check first few chars of argument to ca65 macro?
http://forums.nesdev.com/viewtopic.php?f=2&t=16314
Page 2 of 2

Author:  thefox [ Mon Aug 07, 2017 12:37 pm ]
Post subject:  Re: Check first few chars of argument to ca65 macro?

GradualGames wrote:
Not sure I understand all the syntax there, particularly the double %%'s.

Those are there because of the inner sprintf constructs the format string for the outer sprintf. So, for example .sprintf("%%.%ds", 9) would turn into "%.9s" which is used as the format string in the outer sprintf.

(Note that unlike C sprintf, ca65 does not support specifying the field precision as an argument with "*", so nested sprintfs are needed.)

Author:  GradualGames [ Mon Aug 07, 2017 12:39 pm ]
Post subject:  Re: Check first few chars of argument to ca65 macro?

thefox wrote:
GradualGames wrote:
Not sure I understand all the syntax there, particularly the double %%'s.

Those are there because of the inner sprintf constructs the format string for the outer sprintf. So, for example .sprintf("%%.%ds", 9) would turn into "%.9s" which is used as the format string in the outer sprintf.

(Note that unlike C sprintf, ca65 does not support specifying the field precision as an argument with "*", so nested sprintfs are needed.)

Ah, %% is an escape for itself then? Gotcha. Cool! There's a couple of other things I don't understand in there, it looks like you're doing a multiply on strlens somewhere, too, what's that for? *edit* I think I understand now that < is returning 0 or 1 so you can prevent it from parameterizing sprintf with a negative number, the trickery you mentioned, I assume. Neat.

Author:  thefox [ Mon Aug 07, 2017 12:43 pm ]
Post subject:  Re: Check first few chars of argument to ca65 macro?

GradualGames wrote:
There's a couple of other things I don't understand in there, it looks like you're doing a multiply on strlens somewhere, too, what's that for?

That's the "trickery" I mentioned. (.strlen(ends_with) < .strlen(string)) evaluates to 0 if the ends_with is shorter than string (and 1 otherwise). The multiplication then forces the expression value to 0 to avoid a negative value going into the format string. E.g., "%.-7s" would not be a valid format string.

Author:  GradualGames [ Mon Aug 07, 2017 12:49 pm ]
Post subject:  Re: Check first few chars of argument to ca65 macro?

thefox wrote:
GradualGames wrote:
There's a couple of other things I don't understand in there, it looks like you're doing a multiply on strlens somewhere, too, what's that for?

That's the "trickery" I mentioned. (.strlen(ends_with) < .strlen(string)) evaluates to 0 if the ends_with is shorter than string (and 1 otherwise). The multiplication then forces the expression value to 0 to avoid a negative value going into the format string. E.g., "%.-7s" would not be a valid format string.

I can't seem to get ca65 to be happy with it. Trying to compile the following:

Wondering if it's a linecont issue. Like if I use .linecont + and then add some \ 's if it'll work.

Code:
.define string_ends_with(string, ends_with) .xmatch(.sprintf(.sprintf("%%.%ds%%s", (.strlen(ends_with) < .strlen(string)) * (.strlen(string) - .strlen(ends_with))), string, ends_with), string)
.if string_ends_with("hello", "llo")
    .out "yes"
.else
    .out "no"
.endif

Author:  thefox [ Mon Aug 07, 2017 12:55 pm ]
Post subject:  Re: Check first few chars of argument to ca65 macro?

GradualGames wrote:
thefox wrote:
GradualGames wrote:
There's a couple of other things I don't understand in there, it looks like you're doing a multiply on strlens somewhere, too, what's that for?

That's the "trickery" I mentioned. (.strlen(ends_with) < .strlen(string)) evaluates to 0 if the ends_with is shorter than string (and 1 otherwise). The multiplication then forces the expression value to 0 to avoid a negative value going into the format string. E.g., "%.-7s" would not be a valid format string.


I can't seem to get ca65 to be happy with it. Trying to compile the following:

Wondering if it's a linecont issue. Like if I use .linecont + and then add some \ 's if it'll work.

Code:
.define string_ends_with(string, ends_with) .xmatch(.sprintf(.sprintf("%%.%ds%%s", (.strlen(ends_with) < .strlen(string)) * (.strlen(string) - .strlen(ends_with))), string, ends_with), string)
.if string_ends_with("hello", "llo")
    .out "yes"
.else
    .out "no"
.endif

You should not use parens when calling macros. Try:
Code:
.if string_ends_with "hello", "llo"
    .out "yes"
.else
    .out "no"
.endif

Author:  GradualGames [ Mon Aug 07, 2017 12:57 pm ]
Post subject:  Re: Check first few chars of argument to ca65 macro?

thefox wrote:
You should not use parens when calling macros. Try:
Code:
.if string_ends_with "hello", "llo"
    .out "yes"
.else
    .out "no"
.endif

Oh! :oops: Probably just force of habit with C style macros... I haven't thus far used any in my ca65 programs, only normal ca65 macros.

Author:  tokumaru [ Tue Aug 08, 2017 12:59 am ]
Post subject:  Re: Check first few chars of argument to ca65 macro?

thefox wrote:
It works by stripping off .strlen(string) - .strlen(ends_with) characters from the end of string, then appends ends_with to it, and compares to the original string.

Very clever!

Page 2 of 2 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/