A few days ago, a user reported that a Clarion application was hanging when opening a window that reads a TPS file containing data and thumbnail images stored as BLOBs.
As expected, the TPS file was corrupted. I tried every recovery method I knew, including TPSFIX plus a example file, but the application still kept hanging.
I then wrote a small utility to try to extract the data by reading the file in physical order, or by record number. In every case, though, reading certain records caused FILEERROR() to return what looked like GPF text, and after that the program either became unstable or locked up completely.
At that point I had run out of ideas, but then I remembered the article Liberating Clarion TPS files, which includes a Java utility for reading TPS files. I had nothing to lose, so I gave it a try. To my surprise, it recovered almost all of the records and BLOBs, skipping over pages that contained invalid data.
I immediately wrote a small Clarion program to read the generated CSV and .BIN files and write the data into a new TPS file. That solved the user’s problem.
Afterwards, I decided to turn the experience into a proper tool in case I ever ran into a similar problem again. Since I do not really work with Java, I asked my AI Coding Agent to port the Java utility to C# so I could make changes more comfortably. I expected that to be a fairly involved process, but the agent finished it in a little over five minutes. It then ran comparison tests against the Java version and passed them all.
Seeing that it had no trouble translating the logic to C#, I decided to try taking it all the way to Clarion. A few minutes later, I had Clarion code passing the same tests. From there, I iterated with the agent to build a reusable class with a simple public API.
The result is now available in the tpsparser repository on GitHub. Here is a basic example of how it is used:
Parser TpsParserType
CODE
Result = Parser.Init('C:\data\MyFile.tps')
IF Result <> 0
MESSAGE('Could not open/parse TPS, error:' & Parser.GetError())
RETURN
END
Parser.Set()
LOOP UNTIL Parser.Next()
pre:EmployeeName = Parser.GetField('EmployeeName')
pre:DateHired = Parser.GetDateField('DateHired')
...
END
What I found most interesting is that all of the code and documentation in the repo were written by the agent. The only part I hand-coded was the demo in Test.clw.
My takeaway is that, at least for CLW projects with little UI, coding agents are ready to solve complex Clarion problems.
I plan to use this class in the future. It will come in handy for reading data from other Clarion systems or older versions, avoiding Error 47. It could also be used as a fallback in a future version of FM3.
For reference, I used Pi Coding Agent with a ChatGPT subscription and the GPT-5.5 model.