From: | Geoff Bannoff |
To: | Geoff Bannoff |
llResult = File2Var(lcOutputFile,lcResult)
with
strtofile(lcResult, lcOutputfile)
and the error persists.
.. Geoff
I've spent an evening with this problem, but I'm not getting very far.
I built a test program where I ask your page parser to parse 106 files, then compile the app. I've run it a couple of hundred times, and figured out a few things. The problem file is always the 84th file. (Every time it gets corrupted, I restore from a previous version, ready for the next run.)
Now, the first run of the test program has different results than subsequuent runs.
Quit, then start VFP. The first time through, all 106 files parse properly with no errors. But later in the test program the command "build app fpp from fpp" throws an error on the 84th file (in this case, it's called mpreverse_page.prg). The error looks like this:
Compiling c:\vfp\source\mpreverse_page.prgHeader = nullError in line 484: Statement is not in a procedure. form1 = nullError in line 485: Statement is not in a procedure. lblTitle = nullError in line 486: Statement is not in a procedure. ErrorDisplay = nullError in line 487: Statement is not in a procedure. txtAddress = nullError in line 488: Statement is not in a procedure. lnkGeocode = nullError in line 489: Statement is not in a procedure. txtLatitude = nullError in line 490: Statement is not in a procedure. txtLongitude = nullError in line 491: Statement is not in a procedure. btnGeocode = nullError in line 492: Statement is not in a procedure. lblGeoAddress = nullError in line 493: Statement is not in a procedure. txtQty = nullError in line 494: Statement is not in a procedure. ddlFile = nullError in line 495: Statement is not in a procedure. CTL0013 = nullError in line 496: Statement is not in a procedure. CTL0015 = nullError in line 497: Statement is not in a procedure. btnGo = nullError in line 498: Statement is not in a procedure. btnCancel = nullError in line 499: Statement is not in a procedure. grdNearby = nullError in line 500: Statement is not in a procedure. lblFoot = nullError in line 501: Statement is not in a procedure.HIDDEN CTL0021Error in line 502: Statement is not in a procedure. CTL0021 = nullError in line 503: Statement is not in a procedure.ENDDEFINEError in line 630: Statement is only valid within a class definition.
Running 'build app fpp from fpp' outside of the test program runs just fine.
Then, subsequent runs of my test program (parsing 106 files) fail on the same 84th file. Right after your parser runs, my code gets lost, and the file on the disk now starts with:
*# --- BEGIN GENERATED CODE BOUNDARY --- #* ******************************************************* *** Generated by WebPageParser.prg *** on: 01/17/13 11:08:29 PM *** *** Do not modify manually - class will be overwritten ******************************************************* DEFINECLASS mpreverse_page_WCSX AS mpreverse_pageId = [mpreverse_page]*** Control DefinitionsHIDDEN CTL0002 CTL0002 = nullHeader = null
Then... after the NEXT file (the 85th) is parsed, the first bit of the (already corrupted) 84th file gets lost, and the file on the disk looks like this:
Header = null form1 = null lblTitle = null ErrorDisplay = null txtAddress = null lnkGeocode = null txtLatitude = null txtLongitude = null btnGeocode = null lblGeoAddress = null txtQty = null ddlFile = null CTL0013 = null
I think this is a side effect, rather than the cause of the issue.
I wonder if there's an issue with file handles. Maybe VFP isn't releasing file handles from the WWUtils.File2Var routine, and is running out of them, so isn't able to read the file on the disk correctly? Or maybe it's something screwy with 32 bit Windows 7?
The basics: chkdsk doesn't report any problems; and all files compile correctly outside of the test scenario
Sorry that I can't figure this out further.
.. Geoff
Hi Geoff,
Thanks for taking the time to try and track this down... I don't have time to look at this right now and I think it'll be hard to reproduce with that many files in the first place.
If you say it's so consistent to fail on the xxTH execution could you step into the page parser code and see where it goes wrong? It would seem to me that the problem is that it's reading the file from disk into memory and then doing a string replace in that string. Does the file come back properly? Or does the string replace fail I wonder? I'm guessing the string replace fails, but it's really odd that no FoxPRo error would occur if there's a memory overflow/underflow...
+++ Rick ---
Alas, the problem still arises, but later. With sys(1104) fix, I get up to 82 files parsed without running into corruption. But the 83rd file now gets trashed.
I'll just have to keep the number of recent files below 82, I guess.
.. Geoff
Here's a fix.
After running the page parser, include
=sys(1104)
to purge things cached in memory.
Including sys(1104) after each web page is parsed allows all 73 recently updated files to be parsed without any file corruption.
.. Geoff
I found a problem with the web page parser if I'm updating a lot of files.
My standard "start" program parses any web pages that I have updated in the last 3 days. Yesterday I updated about 30 files, and another 40 today. When I parse all 70 files, the parser consistently mangles 47th one. Restore the 47th web page and generated file from a backup, and it no longer gets parsed (as it now has an older date), but the next time I run the parser on the remaining 69 files, the 47th file gets mangled. Restore that web page and generated file from the backup, and the new 47th file gets mangled.
If I parse a smaller number of files--say just all the ones from yesterday, or just all the ones from today, the code gets generated without any problems. So it's not something in my code--it's in the parser.
When a file gets mangled, all the stuff at the top of the file gets lost--the usual stub and all the procedures I wrote--are lost. Here is the beginning of a mangled file:
Header = null form1 = null lblTitle = null ErrorDisplay = null txtAddress = null lnkGeocode = null txtLatitude = null txtLongitude = null btnGeocode = null lblGeoAddress = null txtQty = null ddlFile = null CTL0013 = null CTL0015 = null btnGo = null btnCancel = null grdNearby = null lblFoot = nullHIDDEN CTL0021 CTL0021 = nullFUNCTION Initialize(loPage)LOCAL __lcHtmlDODEFAULT(loPage)THIS.Header = CREATEOBJECT("wwwebhead",THIS.Page,"Header")THIS.AddControl(THIS.Header)
There is nothing before this in the file. Everything has gotten overwritten.
A workaround is to count the number of files being parsed, and reset the parser, like this:
m.nFiles=ADIR(aFP,'C:\inetpub\wwwroot\fpp\*.fp') && list of all web filesFOR m.nCount =1 TO m.nFiles* check modification dateIF aFP[m.nCount,3]>DATE()-3 m.pcount = m.pcount + 1IF m.pcount> 30RELEASEPROCEDURE WebPageParserSETPROCEDURETO WebPageParser additive m.pCount = 0endif ? m.pcount,' parsing',aFP(m.nCount,1) oParser.ParseToFile('c:\inetpub\wwwroot\fpp\'+aFP(m.nCount,1))ENDIFendfor
Maybe it takes about 47 files to overflow a string somewhere in WebPageParser?
It's been awhile since the parser has mangled any of my files, and we have backup system in place to handle that eventuality. But it would be nice to get rid of this problem.
.. Geoff