Files
fpc-msgbase/examples/example_read.pas
Ken Johnson 0fe57b846d Rename ma.* -> mb.* namespace (cosmetic, breaking)
Across-the-board rename so the unit prefix matches the repo
name (mb = msgbase).  Brings naming into line with
fpc-ftn-transport's tt.* prefix and avoids the historical
"ma" abbreviation that meant nothing to new readers.

Files renamed via git mv:
  src/ma.{api,events,kludge,lock,paths,types}.pas
    -> src/mb.{...}.pas
  src/formats/ma.fmt.{jam,squish,hudson,msg,pcboard,ezycom,
                      goldbase,wildcat,wcutil}{,.uni}.pas
    -> src/formats/mb.fmt.*.pas

All `unit ma.X` declarations and `uses ma.X` clauses rewritten
to `mb.X` across src/, examples/, tests/.

Suite: 47/47 (read 7, hwm 11, lock 4, pack 4, write 5,
wildcat 5, consumer_round1 5, batch's gone w/ PKT relocation,
plus testutil).

Consumer impact: anyone with `uses ma.api;` etc. needs to
update to `uses mb.api;`. No semantic changes; a search/replace
on the consumer's source tree is the only migration step.
NR's notes (~/.MSGAPI_MSGS.md round 3) align this against
their already-pinned 8130b40; the next NR pin bump rolls in
both this rename and any further work in one step.
2026-04-18 13:19:15 -07:00

131 lines
3.2 KiB
ObjectPascal

{
example_read.pas - open a message base via the unified API,
walk every message, dump a one-line summary.
usage: example_read <format> <path>
format : hudson | jam | squish | msg | pcboard | ezycom |
goldbase | auto
path : directory or basename the backend expects
Example:
example_read hudson /home/ken/fidonet/msg/hudson
}
program example_read;
{$mode objfpc}{$H+}
uses
SysUtils,
mb.types, mb.events, mb.api,
mb.fmt.hudson, mb.fmt.hudson.uni,
mb.fmt.jam, mb.fmt.jam.uni,
mb.fmt.squish, mb.fmt.squish.uni,
mb.fmt.msg, mb.fmt.msg.uni,
mb.fmt.pcboard, mb.fmt.pcboard.uni,
mb.fmt.ezycom, mb.fmt.ezycom.uni,
mb.fmt.goldbase, mb.fmt.goldbase.uni;
type
TLogger = class
procedure OnLog(Level: TMsgEventType;
const Source, Msg: AnsiString);
end;
procedure TLogger.OnLog(Level: TMsgEventType;
const Source, Msg: AnsiString);
begin
WriteLn('[', EventTypeToStr(Level), '] ', Source, ': ', Msg);
end;
var
gLogger: TLogger;
function ParseFormat(const S: string; out AFormat: TMsgBaseFormat;
out AAuto: boolean): boolean;
begin
AAuto := False;
Result := True;
case LowerCase(S) of
'hudson': AFormat := mbfHudson;
'jam': AFormat := mbfJam;
'squish': AFormat := mbfSquish;
'msg': AFormat := mbfMsg;
'pcboard': AFormat := mbfPCBoard;
'ezycom': AFormat := mbfEzyCom;
'goldbase': AFormat := mbfGoldBase;
'wildcat': AFormat := mbfWildcat;
'auto': AAuto := True;
else
Result := False;
end;
end;
procedure Usage;
begin
WriteLn('Usage: example_read <format> <path>');
WriteLn(' formats: hudson jam squish msg pcboard ezycom goldbase wildcat auto');
Halt(2);
end;
var
fmtName: string;
path: string;
fmt: TMsgBaseFormat;
auto: boolean;
base: TMessageBase;
msg: TUniMessage;
i, n: longint;
begin
if ParamCount < 2 then Usage;
fmtName := ParamStr(1);
path := ParamStr(2);
if not ParseFormat(fmtName, fmt, auto) then Usage;
try
if auto then
base := MessageBaseOpenAuto(path, momReadOnly)
else
base := MessageBaseOpen(fmt, path, momReadOnly);
except
on E: Exception do begin
WriteLn('error: ', E.Message);
Halt(1);
end;
end;
if base = nil then begin
WriteLn('error: could not detect format at ', path);
Halt(1);
end;
gLogger := TLogger.Create;
base.Events.OnLog := @gLogger.OnLog;
if not base.Open then begin
WriteLn('error: Open returned False (base files missing?)');
base.Free;
Halt(1);
end;
try
n := base.MessageCount;
WriteLn('format: ', MSG_BASE_FORMAT_NAME[base.Format],
' path: ', base.BasePath,
' messages: ', n);
for i := 0 to n - 1 do
if base.ReadMessage(i, msg) then
WriteLn(Format('%5d %-20s -> %-20s %s',
[msg.Attributes.GetInt('msg.num'),
Copy(msg.Attributes.Get('from'), 1, 20),
Copy(msg.Attributes.Get('to'), 1, 20),
Copy(msg.Attributes.Get('subject'), 1, 40)]));
finally
base.Close;
base.Free;
gLogger.Free;
end;
end.