summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/docdump/docdump.lpi65
-rw-r--r--src/docdump/docdump.lpr87
-rw-r--r--src/docdump/filestreamhelper.pas35
-rw-r--r--src/docdump/readheader.pas114
4 files changed, 301 insertions, 0 deletions
diff --git a/src/docdump/docdump.lpi b/src/docdump/docdump.lpi
new file mode 100644
index 00000000..182a9da4
--- /dev/null
+++ b/src/docdump/docdump.lpi
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<CONFIG>
+ <ProjectOptions>
+ <Version Value="7"/>
+ <General>
+ <SessionStorage Value="InIDEConfig"/>
+ <MainUnit Value="0"/>
+ <TargetFileExt Value=""/>
+ <UseAppBundle Value="False"/>
+ </General>
+ <VersionInfo>
+ <ProjectVersion Value=""/>
+ </VersionInfo>
+ <PublishOptions>
+ <Version Value="2"/>
+ <IgnoreBinaries Value="False"/>
+ <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+ <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
+ </PublishOptions>
+ <RunParams>
+ <local>
+ <FormatVersion Value="1"/>
+ <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
+ </local>
+ </RunParams>
+ <Units Count="5">
+ <Unit0>
+ <Filename Value="docdump.lpr"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="docdump"/>
+ </Unit0>
+ <Unit1>
+ <Filename Value="../IPFEscapeCodes.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="IPFEscapeCodes"/>
+ </Unit1>
+ <Unit2>
+ <Filename Value="../IPFFileFormatUnit.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="IPFFileFormatUnit"/>
+ </Unit2>
+ <Unit3>
+ <Filename Value="readheader.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="readheader"/>
+ </Unit3>
+ <Unit4>
+ <Filename Value="filestreamhelper.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="filestreamhelper"/>
+ </Unit4>
+ </Units>
+ </ProjectOptions>
+ <CompilerOptions>
+ <Version Value="8"/>
+ <SearchPaths>
+ <IncludeFiles Value="$(ProjOutDir)/"/>
+ <OtherUnitFiles Value="../"/>
+ <UnitOutputDirectory Value="units"/>
+ </SearchPaths>
+ <Other>
+ <CompilerPath Value="$(CompPath)"/>
+ </Other>
+ </CompilerOptions>
+</CONFIG>
diff --git a/src/docdump/docdump.lpr b/src/docdump/docdump.lpr
new file mode 100644
index 00000000..4415a0a8
--- /dev/null
+++ b/src/docdump/docdump.lpr
@@ -0,0 +1,87 @@
+program docdump;
+
+{$mode objfpc}{$H+}
+
+uses
+ {$IFDEF UNIX}{$IFDEF UseCThreads}
+ cthreads,
+ {$ENDIF}{$ENDIF}
+ Classes, SysUtils, IPFFileFormatUnit, IPFEscapeCodes, CustApp, readheader,
+ filestreamhelper;
+
+type
+
+ { TDocDump }
+
+ TDocDump = class(TCustomApplication)
+ private
+ FIn: TFileStream;
+ FOut: TFileTextStream;
+ protected
+ procedure DoRun; override;
+ public
+ constructor Create(TheOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure WriteHelp; virtual;
+ end;
+
+{ TDocDump }
+
+procedure TDocDump.DoRun;
+var
+ ErrorMsg: String;
+begin
+ // quick check parameters
+ ErrorMsg:=CheckOptions('h','help');
+ if ErrorMsg<>'' then begin
+ ShowException(Exception.Create(ErrorMsg));
+ Terminate;
+ Exit;
+ end;
+
+ // parse parameters
+ if HasOption('h','help') then begin
+ WriteHelp;
+ Terminate;
+ Exit;
+ end;
+
+ FIn := TFileStream.Create(ParamStr(1), fmOpenRead);
+ FOut := TFileTextStream.Create(ExtractFileName(ParamStr(1))+'.txt', fmCreate);
+ try
+ FOut.WriteLn(Format('File name: %s (%d bytes)', [ExtractFileName(ParamStr(1)), FIn.Size]));
+ ProcessHeader(FIn, FOut);
+ finally
+ FIn.Free;
+ FOut.Free;
+ end;
+ // stop program loop
+ Terminate;
+end;
+
+constructor TDocDump.Create(TheOwner: TComponent);
+begin
+ inherited Create(TheOwner);
+ StopOnException:=True;
+end;
+
+destructor TDocDump.Destroy;
+begin
+ inherited Destroy;
+end;
+
+procedure TDocDump.WriteHelp;
+begin
+ { add your help code here }
+ writeln('Usage: ',ExeName,' -h');
+end;
+
+var
+ Application: TDocDump;
+
+begin
+ Application:=TDocDump.Create(nil);
+ Application.Run;
+ Application.Free;
+end.
+
diff --git a/src/docdump/filestreamhelper.pas b/src/docdump/filestreamhelper.pas
new file mode 100644
index 00000000..ff831a91
--- /dev/null
+++ b/src/docdump/filestreamhelper.pas
@@ -0,0 +1,35 @@
+unit filestreamhelper;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils;
+
+type
+ TFileTextStream = class(TFileStream)
+ public
+ procedure WriteLn(const fmt: String; const args: array of const);
+ procedure WriteLn(const s: String);
+ end;
+
+implementation
+
+{ TFileTextStream }
+
+procedure TFileTextStream.WriteLn(const fmt: String; const args: array of const);
+var
+ temp: String;
+begin
+ temp := Format(fmt, args) + LineEnding;
+ Write(temp[1], Length(temp));
+end;
+
+procedure TFileTextStream.WriteLn(const s: String);
+begin
+ self.WriteLn('%s', [s]);
+end;
+
+end.
+
diff --git a/src/docdump/readheader.pas b/src/docdump/readheader.pas
new file mode 100644
index 00000000..0c5f7bc8
--- /dev/null
+++ b/src/docdump/readheader.pas
@@ -0,0 +1,114 @@
+unit readheader;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, filestreamhelper;
+
+procedure ProcessHeader(AIn: TFileStream; AOut: TFileTextStream);
+
+implementation
+
+uses
+ IPFFileFormatUnit;
+
+type
+ TWord = record
+ b1: AnsiChar;
+ b2: AnsiChar;
+ end;
+
+ Unsigned_31 = 0 .. (1 shl 31) - 1; // 31 bit type
+
+ TOverlayID = packed record
+ b1: Byte;
+ b2: Byte;
+ b3: Byte;
+ end;
+
+ TOverlaySearchStart = bitpacked record
+ SearchOffset: Unsigned_31;
+ IsRec16bitSize: boolean;
+ end;
+
+
+procedure ProcessHeader(AIn: TFileStream; AOut: TFileTextStream);
+var
+ hdr: TPHelpFileHeader;
+ bytes: integer;
+ s: string;
+ w: TWord;
+ i: uint32;
+ t0: TOverlayID;
+ t1: TOverlaySearchStart;
+begin
+ New(hdr);
+ try
+ AIn.Seek(0, soBeginning);
+ bytes := AIn.Read(hdr^, SizeOf(THelpFileHeader));
+ if bytes <> SizeOf(THelpFileHeader) then
+ raise Exception.Create('Failed to read complete file header');
+
+ if hdr^.ID <> INF_HEADER_ID then
+ raise Exception.Create('This is not an OS/2 help file');
+
+ AOut.WriteLn('Header Section');
+ t0 := TOverlayID(hdr^.ID);
+ s := hdr^.ID;
+ AOut.WriteLn(Format(' hdr.id: %4.2x %2x %2x ("%s") : Magic word' ,[Byte(hdr^.id[0]), Byte(hdr^.id[1]), Byte(hdr^.id[2]), s]));
+ if (hdr^.flags and $01) > 0 then
+ s := 'INF'
+ else
+ s := 'HLP';
+ AOut.WriteLn(Format(' hdr.flags: %8.2x (%s format) : File format' ,[hdr^.flags, s]));
+ AOut.WriteLn(Format(' hdr.size: %8.4x (%0:7d bytes) : Size of this header structure', [hdr^.hdrsize]));
+ AOut.WriteLn(Format(' hdr.version: %6d.%d : version of file format?', [hdr^.version_hi, hdr^.version_lo]));
+ AOut.WriteLn(Format(' hdr.ntoc: %8.4x (%0:13d) : No of TOC entries', [hdr^.ntoc]));
+ AOut.WriteLn(Format(' hdr.tocstart: %8.8x (%0:7d bytes) : 32bit file offset to start of TOC', [hdr^.tocstart]));
+ AOut.WriteLn(Format(' hdr.toclen: %8.8x (%0:7d bytes) : bytes occupied by TOC entries', [hdr^.toclen]));
+ AOut.WriteLn(Format(' hdr.tocoffsetsstart: %8.8x (%0:7d bytes) : file offset to array of TOC offsets', [hdr^.tocoffsetsstart]));
+ AOut.WriteLn(Format(' hdr.nres: %8.4x (%0:13d) : number of panels with resource numbers', [hdr^.nres]));
+ AOut.WriteLn(Format(' hdr.resstart: %8.8x (%0:7d bytes) : 32bit file offset of ressource number table', [hdr^.resstart]));
+ AOut.WriteLn(Format(' hdr.nname: %8.4x (%0:13d) : number of panels with textual name', [hdr^.nname]));
+ AOut.WriteLn(Format(' hdr.namestart: %8.8x (%0:7d bytes) : 32bit file offset to panel name table', [hdr^.namestart]));
+ AOut.WriteLn(Format(' hdr.nindex: %8.4x (%0:13d) : number of index entries', [hdr^.nindex]));
+ AOut.WriteLn(Format(' hdr.indexstart: %8.8x (%0:7d bytes) : 32bit file offset to index table', [hdr^.indexstart]));
+ AOut.WriteLn(Format(' hdr.indexlen: %8.8x (%0:7d bytes) : size of index table', [hdr^.indexlen]));
+ AOut.WriteLn(Format(' hdr.icmdCount: %8.4x (%0:13d) : number of icmd index items', [hdr^.icmdCount]));
+ AOut.WriteLn(Format(' hdr.icmdOffset: %8.8x (%0:7d bytes) : file offset to icmd index items', [hdr^.icmdOffset]));
+ AOut.WriteLn(Format(' hdr.icmdSize: %8.8x (%0:7d bytes) : size of icmd index table', [hdr^.icmdSize]));
+ t1 := TOverlaySearchStart(hdr^.searchstart);
+ i := t1.SearchOffset;
+ AOut.WriteLn(Format(' hdr.searchstart :31 %8.8x (%0:7d bytes) : 31 bit file offset of full text search table', [i, i]));
+ if t1.IsRec16bitSize then
+ s := 'search rec is 16bit size'
+ else
+ s := 'search rec is 8bit size';
+ AOut.WriteLn(Format(' hdr.recSize :1 %s (%s) : if high bit set, search record size is 16bit', [BoolToStr(t1.IsRec16bitSize, True), s]));
+ AOut.WriteLn(Format(' hdr.searchlen: %8.8x (%0:7d bytes) : size of full text search table', [hdr^.searchlen]));
+ AOut.WriteLn(Format(' hdr.nslots: %8.4x (%0:13d) : number of "slots"', [hdr^.nslots]));
+ AOut.WriteLn(Format(' hdr.slotsstart: %8.8x (%0:7d bytes) : 32bit file offset of the slots array', [hdr^.slotsstart]));
+ AOut.WriteLn(Format(' hdr.dictlen: %8.8x (%0:7d bytes) : bytes occupied by the "dictionary"', [hdr^.dictlen]));
+ AOut.WriteLn(Format(' hdr.ndict: %8.4x (%0:13d) : number of entries in the dictionary', [hdr^.ndict]));
+ AOut.WriteLn(Format(' hdr.dictstart: %8.8x (%0:7d bytes) : 32bit file offset to start of dictionary', [hdr^.dictstart]));
+ AOut.WriteLn(Format(' hdr.imgstart: %8.8x (%0:7d bytes) : 32bit file offset to image data', [hdr^.imgstart]));
+ AOut.WriteLn(Format(' hdr.maxCVTIndex: %8.2x (%0:13d) : highest index inside panel''s local dictionary', [hdr^.maxCVTIndex]));
+ AOut.WriteLn(Format(' hdr.nlsstart: %8.8x (%0:7d bytes) : 32bit file offset of NLS table', [hdr^.nlsstart, hdr^.nlsstart]));
+ AOut.WriteLn(Format(' hdr.nlslen: %8.8x (%0:7d bytes) : size of NLS table', [hdr^.nlslen]));
+ AOut.WriteLn(Format(' hdr.extstart: %8.8x (%0:7d bytes) : 32bit file offset of extended data block', [hdr^.extstart]));
+ AOut.WriteLn(Format(' hdr.reserved: %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x : for future use. set to zero.',
+ [hdr^.reserved[0], hdr^.reserved[1], hdr^.reserved[2], hdr^.reserved[3], hdr^.reserved[4], hdr^.reserved[5],
+ hdr^.reserved[6], hdr^.reserved[7], hdr^.reserved[8], hdr^.reserved[9], hdr^.reserved[10], hdr^.reserved[11] ]));
+ AOut.WriteLn(Format(' hdr.title: "%s" : ASCII title of database', [hdr^.title]));
+
+{ title: array[ 0..47 ] of char; // ASCII title of database
+}
+ finally
+ Dispose(hdr);
+ end;
+end;
+
+end.
+