Turn a Lazarus LRS Resource into Readable LFM with lrstolfm

lrstolfm has one job: turning a binary Lazarus LRS resource into readable LFM text. It never touches the source file while it does it. Installed here as lrstolfm from Lazarus 3.0, packaged as lcl-utils-3.0 3.0+dfsg1-8build3. Ten minutes, one shell, one readable LRS file, and a place to save the output.

The workflow is unprivileged throughout. Do not reach for sudo unless a genuine file-permission problem forces it.

1. Confirm the installed command

$ command -v lrstolfm
/usr/bin/lrstolfm
$ dpkg-query -W -f='${Package} ${Version}\n' lcl-utils-3.0
lcl-utils-3.0 3.0+dfsg1-8build3

The manual calls this the Lazarus Resource Translator, and its interface is deliberately tiny: no documented options at all, just an input filename and an optional resource name.

Checkpoint: make sure the first path really is the LRS source you mean to inspect. lrstolfm will not edit it, but pointing it at the wrong file still hands you a convincing, irrelevant answer.

2. Get the usage line, do not guess at flags

Run it with no arguments for the short synopsis:

$ lrstolfm
Usage: lrstolfm resourcefilename [resourcename]

That is the documented way to see it, because --help is not supported. In this build, an unrecognised argument is treated as an input filename, so lrstolfm --help tries to open a file literally named --help and reports an input error rather than help text. The upside of having no options: filename first, optional resource name second, and that is the whole interface.

3. Convert the first resource to standard output

$ lrstolfm /path/to/resources.lrs
object MainForm: TMainForm
  Caption = 'Main form'
  Left = 100
  Top = 100
end

That output is illustrative; your object name and properties come from your own resource. With no resource name given, the program grabs the first LazarusResources.Add entry it finds in the LRS file and converts that.

Redirect to a file when you want one, and pick a new destination name first so a failed conversion cannot truncate an existing form:

$ lrstolfm /path/to/resources.lrs > /path/to/preview.lfm
$ test -s /path/to/preview.lfm && printf '%s\n' 'LFM output is non-empty'
LFM output is non-empty

Redirection is the shell's job, not lrstolfm's: the program writes to stdout and puts diagnostics on stderr regardless. The original LRS file stays untouched either way, so if the result is wrong, just remove or replace the preview.

4. Select a resource by name

An LRS file can hold more than one resource. Give the exact name as the second argument:

$ lrstolfm /path/to/resources.lrs MainForm > /path/to/main-form.lfm
$ sed -n '1,12p' /path/to/main-form.lfm
object MainForm: TMainForm
  Caption = 'Main form'
  Left = 100
  Top = 100
  Width = 800
  Height = 600

MainForm is the name stored inside the file, not the filename and not the Pascal class name unless those happen to match. The lookup is exact: a misspelling gives you resource-not-found, not a fuzzy guess.

Do not know the names? Grep the LRS source for the entries themselves:

$ rg "^LazarusResources\.Add\(" /path/to/resources.lrs
LazarusResources.Add('MainForm','FORM',[

That file is Pascal-source-like text. Treat it as data: read the quoted name, quote it again as a shell argument, and never paste arbitrary text from it into a command line.

5. Verify before you replace a form

$ lrstolfm /path/to/resources.lrs MainForm > /path/to/main-form.lfm
$ status=$?
$ printf 'lrstolfm status: %s\n' "$status"
lrstolfm status: 0
$ sed -n '1,8p' /path/to/main-form.lfm
$ tail -n 4 /path/to/main-form.lfm

Status 0 just means the process finished; it does not prove you picked the resource you meant, so eyeball the opening declaration and a couple of properties against what you expect. An error means preserve the old LFM and go investigate the input path, the resource name, or the resource format.

For a replacement you can actually walk back, write to a temporary name, diff it, then move it:

$ lrstolfm /path/to/resources.lrs MainForm > /path/to/MainForm.lfm.new
$ diff -u /path/to/MainForm.lfm /path/to/MainForm.lfm.new
$ mv /path/to/MainForm.lfm.new /path/to/MainForm.lfm

Warning: that final mv changes project state, so only run it once the diff makes sense to you. Recovery, if you need it, comes from version control or your own backup, not from lrstolfm.

Common traps

Missing input file is not a conversion failure. Check path and permission without elevating:

$ test -r /path/to/resources.lrs && printf '%s\n' 'input is readable'
$ ls -l /path/to/resources.lrs

Done means