Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Core » [solved] CParser GetColumn bugfix
[solved] CParser GetColumn bugfix [message #52555] Tue, 22 October 2019 11:24 Go to next message
cbpporter is currently offline  cbpporter
Messages: 1400
Registered: September 2007
Senior Contributor
Calling GetColumn when the internal CParser::lineptr points to another line (which is rare in practice, but possible, can provide test case but don't think its needed) does not handle new-lines.

Fix:

int CParser::Pos::GetColumn(int tabsize) const
{
	int pos = 1;
	for(const char *s = lineptr; s < ptr; s++) {
		if(*s == CParser::LINEINFO_ESC) {
			s++;
			while(s < ptr && *s != CParser::LINEINFO_ESC)
				if(*s++ == '\3')
					pos = atoi(s);
		}
		else
		if(*s == '\n')
			pos = 0;  // FIX
		else
		if(*s == '\t')
			pos = (pos + tabsize - 1) / tabsize * tabsize + 1;
		else
			pos++;
	}
	return pos;
}


Additionally, I'm using CParser to parse more complicated input where simple SkipSpaces(true) doesn't works so I'm manually skipping whitespaces, but comments are still automatic.

I added the following overload to handle this:

CParser::CParser(const char *ptr, bool skipSpaces)
: term(ptr), wspc(ptr), lineptr(ptr)
{
	line = 1;
	skipspaces = skipSpaces;
	skipcomments = true;
	nestcomments = false;
	uescape = true;
	if (skipSpaces)
		Spaces();
}


I need a solution that support hundreds of CParser created on the spot for random code jumping that do not eat whitespaces since they are syntactically significant.

[Updated on: Thu, 31 October 2019 11:34]

Report message to a moderator

Re: CParser GetColumn bugfix [message #52574 is a reply to message #52555] Tue, 22 October 2019 23:52 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
Should not that be pos = 1?

Mirek
Re: CParser GetColumn bugfix [message #52575 is a reply to message #52555] Tue, 22 October 2019 23:55 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
I think the whitespace overloaded can be worked around by default contructor, setting CParser up (e.g. NoWhiteSpace), then use Set to start parsing. This is how it was meant...
Re: CParser GetColumn bugfix [message #52581 is a reply to message #52555] Wed, 23 October 2019 15:57 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
cbpporter wrote on Tue, 22 October 2019 11:24
Calling GetColumn when the internal CParser::lineptr points to another line (which is rare in practice, but possible, can provide test case but don't think its needed) does not handle new-lines.


Would it be possible to provide testcase anyway? More I think about this, less apparent it seems.
Re: CParser GetColumn bugfix [message #52607 is a reply to message #52581] Mon, 28 October 2019 11:24 Go to previous messageGo to next message
cbpporter is currently offline  cbpporter
Messages: 1400
Registered: September 2007
Senior Contributor
It is indeed pos = 1.

It was 1 at one time then I tried to fix it in Spaces and that fix required 0, but it is easier and more reliable to fix in GetColumn.

This is the shortest real life example I could find:

CONSOLE_APP_MAIN {
	String s =
"+ /* \n"
"  */ a";

	CParser p(s);
	
	if (p.Char('+')) {
		Point z(p.GetLine(), p.GetPos().GetColumn());
		Cout() << z.x << ", " << z.y << ": " << p.ReadId() << "\n";
	}
}
Re: CParser GetColumn bugfix [message #52608 is a reply to message #52575] Mon, 28 October 2019 11:26 Go to previous messageGo to next message
cbpporter is currently offline  cbpporter
Messages: 1400
Registered: September 2007
Senior Contributor
mirek wrote on Wed, 23 October 2019 00:55
I think the whitespace overloaded can be worked around by default contructor, setting CParser up (e.g. NoWhiteSpace), then use Set to start parsing. This is how it was meant...

I'll test and see if that works. Thank you!
Re: CParser GetColumn bugfix [message #52615 is a reply to message #52607] Wed, 30 October 2019 08:40 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12105
Registered: November 2005
Ultimate Member
cbpporter wrote on Mon, 28 October 2019 11:24
It is indeed pos = 1.

It was 1 at one time then I tried to fix it in Spaces and that fix required 0, but it is easier and more reliable to fix in GetColumn.

This is the shortest real life example I could find:

CONSOLE_APP_MAIN {
	String s =
"+ /* \n"
"  */ a";

	CParser p(s);
	
	if (p.Char('+')) {
		Point z(p.GetLine(), p.GetPos().GetColumn());
		Cout() << z.x << ", " << z.y << ": " << p.ReadId() << "\n";
	}
}


Thank you. I believe I have that fixed 'correctly' (in Spaces0 etc...), in the trunk.

Mirek
Re: CParser GetColumn bugfix [message #52617 is a reply to message #52615] Wed, 30 October 2019 10:12 Go to previous messageGo to next message
cbpporter is currently offline  cbpporter
Messages: 1400
Registered: September 2007
Senior Contributor
Here is my exact code from Spaces0 Surprised :
if(*term++ == '\n') {
						line++;
						//lineptr = term;
					}


This is the fix I retired for my new one, that worked better. But I didn't update GetChar and Skip Term.

But I'll test out you new fix.

Luckily, I have 170 test cases ready to run, some of them testing column too.
Re: CParser GetColumn bugfix [message #52624 is a reply to message #52617] Thu, 31 October 2019 11:33 Go to previous message
cbpporter is currently offline  cbpporter
Messages: 1400
Registered: September 2007
Senior Contributor
The bugfix looks like it works! The GetChar did it.

I also changed my code to use Set.

New CParser constructor not needed anymore.

Thank you!

Previous Topic: Long time running program and Vector
Next Topic: Add compilable testcases for nontrivial problems!
Goto Forum:
  


Current Time: Tue Nov 19 07:05:26 CET 2019

Total time taken to generate the page: 0.03639 seconds