Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kustom specifier and space #7

Closed
kryosaurr opened this issue Nov 20, 2016 · 7 comments
Closed

kustom specifier and space #7

kryosaurr opened this issue Nov 20, 2016 · 7 comments
Assignees

Comments

@kryosaurr
Copy link

kryosaurr commented Nov 20, 2016

Hello, i have a sscanf custom specifiers to check if gang name is exists.
Here is my code:

SSCANF:gang(string[])
{
	printf("SSCANF:gang string is \"%s\"", string);
	new ret;
	if ('0' <= string[0] <= '9')
	{
		ret = strval(string);
		if(Iter_Contains(Gangs, ret))
			return ret;
	}

	foreach(new i : Gangs)
	{
		if(!strcmp(g_Gang[i][gname], string, true))
			return i;
	}
	return -1;
}

The problem is, it doesn't work while i'm trying to find a gang that have spaces in it.
I've debugged that code by printing "string" variable, and i found out that the string is getting cut off at space.

new testname[12] = "Gang name", id;
sscanf(testname, "k<gang>", id); // Prints SSCANF:gang string is "Gang"
testname = "Gang_name";
sscanf(testname, "k<gang>", id); // Prints SSCANF:gang string is "Gang_name"

I also tested it with default weapon kustom specifier,

sscanf("Brass Knuckles", "k<weapon>", id); // prints "Brass", id = -1
sscanf("Knife", "k<weapon>", id); // Works fine
@maddinat0r
Copy link
Collaborator

Well, sscanf splits the input string by spaces per default. You'd have to change the delimiter char from space to something else to match values with spaces in them.

@Crayder
Copy link

Crayder commented Nov 25, 2016

Well, sscanf splits the input string by spaces per default. You'd have to change the delimiter char from space to something else to match values with spaces in them.

Yes but I completely understand his point. Regular string specifiers take what's left of the string (unless taking a single word because of following parameters), these should too.

@maddinat0r
Copy link
Collaborator

Yeah, I also do get his point, that's why I'm not closing this issue yet.
I'll definitely take a look at that when I get some more free time.

@maddinat0r maddinat0r self-assigned this Nov 25, 2016
@maddinat0r
Copy link
Collaborator

I took a look at the source code and did some tests. The specifiers themselves don't know their position in the format string. I could change that of course, but @Y-Less left that comment:

// End of the format string - if we're here we've got all the
// parameters but there is extra string or variables, which may
// indicate their code needs fixing, for example:
// sscanf(data, "ii", var0, var1, var3, var4);
// There is only two format specifiers, but four returns.  This may
// also be reached if there is too much input data, but that is
// considered OK as that is likely a user's fault.

Based on this the plugin treats having too much input data is a user's fault. So introducing a "consume what's left of the input data if it's the last string-consuming specifier, even though there are delimiter characters" behavior would be a breaking change.

I'd like to hear @Y-Less thoughts on this. If he deems that as valid behavior, I'll look into implementing this.

For now you'll have to manually set a character as delimiter that you're sure of won't occur in your input string.

@Y-Less
Copy link
Owner

Y-Less commented Dec 30, 2017

s consumes everything already. I'm not sure what happens with:

sscanf("p<,>s[32]", "hello there, world", dest);

And you can prevent this behaviour with:

sscanf("s[32] ", "hello there, world", dest);

There the trailing space is actually important, as the s specifier looks ahead to see if there is another thing after it (but doesn't care what it is, space is not null, but also not a specifier).

There's no real reason why k can't do the same thing.

@Y-Less
Copy link
Owner

Y-Less commented Dec 30, 2017

OK, this line is the one that tells s whether to consume everything or up to the next delimiter. So you're right, the specifier itself doesn't know its own position, but it has a bool all parameter.

@maddinat0r
Copy link
Collaborator

Alright, I think that the kustom specifier should adopt that behavior, as it does the same as the string specifier, with the only difference of passing the parsed value to a PAWN callback instead of directly storing it into a variable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants