home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / tptools.zip / BINED.ZIP / BINED.PAS < prev    next >
Pascal/Delphi Source File  |  1987-12-21  |  18KB  |  574 lines

  1. {                          BINED.PAS
  2.                            BINED 4.0
  3.              Copyright (c) 1985, 87 by Borland International, Inc.            }
  4.  
  5. {$I-}
  6. {$S-}
  7. {$R-}
  8.  
  9. unit BinEd;
  10. {-The Borland binary editor interface for Turbo Pascal}
  11.  
  12. interface
  13.  
  14. const
  15.   MaxFileSize = $FFE0;        {Maximum file size editable by Binary Editor}
  16.   EdOptInsert = $1;           {Insert on flag}
  17.   EdOptIndent = $2;           {Autoindent on flag}
  18.   EdOptTAB = $8;              {Tab on flag}
  19.   EdOptBlock = $10;           {Show marked block}
  20.   EdOptNoUpdate = $20;        {Don't update screen when entering editor}
  21.   EventKBflag = 1;            {Scroll, num or caps locks modified mask}
  22.   CAnorm = #255#1;            {Activates CRT "normal" attribute}
  23.   CAlow = #255#2;             {Activates CRT "low"        -    }
  24.   CAblk = #255#3;             {Activates CRT "block"      -    }
  25.   CAerr = #255#4;             {Activates CRT "error"      -    }
  26.   EdStatTextMod = 1;          {Text buffer modified mask}
  27.  
  28. type
  29.   AttrArray = array[0..3] of Byte;
  30.   ASCIIZ = array[0..255] of Char;
  31.   ASCIIZptr = ^ASCIIZ;
  32.   TextBuffer = array[0..$FFF0] of Char;
  33.  
  34.   CRTinsStruct =              {CRT installation structure}
  35.   record
  36.     CRTtype : Byte;           {1=IBM, 0=Non}
  37.     CRTx1, CRTy1,
  38.     CRTx2, CRTy2 : Byte;      {Initial window size}
  39.     CRTmode : Byte;           {Initial mode 0-3,7 or FF(default)}
  40.     CRTsnow : Byte;           {0 if no snow, don't care for mono}
  41.     AttrMono : AttrArray;     {CRT attributes for mono mode}
  42.     AttrBW : AttrArray;       {CRT attributes for b/w modes}
  43.     AttrColor : AttrArray;    {CRT attributes for color modes}
  44.   end;
  45.   CIptr = ^CRTinsStruct;
  46.  
  47.   EdInsStruct =               {Command table installation structure}
  48.   record
  49.     ComTablen : Word;         {Maximum length of command table}
  50.     ComTab : TextBuffer;      {Command table}
  51.   end;
  52.   EIptr = ^EdInsStruct;
  53.  
  54.   MIinsStruct =               {Main installation structure}
  55.   record
  56.     Ver : Byte;               {Main version}
  57.     VerSub : Byte;            {Sub version}
  58.     VerPatch : Char;          {Patch level}
  59.     CPUmhz : Byte;            {CPU speed for delays}
  60.     CIstruct : CIptr;         {Points to CRT installation record}
  61.     EIstruct : EIptr;         {Points to Editor installation area}
  62.     DefExt : ASCIIZptr;       {Points to ASCIIZ default extension}
  63.   end;
  64.   MIptr = ^MIinsStruct;
  65.  
  66.   EdCB =                      {Editor control block in detail}
  67.   record
  68.     x1, y1, x2, y2 : Byte;    {Upper left and lower right corners of editor window}
  69.     DataSeg : Word;           {Segment address of editor data area}
  70.     DataSegLen : Word;        {Requested data area length (bytes)}
  71.     Options : Word;           {Bit flags for editor options}
  72.     FileStr : ASCIIZptr;      {Points to ASCIIZ filename}
  73.     Commands : ASCIIZptr;     {Points to ASCIIZ string of editor commands}
  74.     Reserved1 : ASCIIZptr;    {Not used here}
  75.     Reserved2 : ASCIIZptr;    {Not used here}
  76.     Event : Pointer;          {Points to event handling procedure}
  77.     Buffer : ^TextBuffer;     {Points to text area}
  78.     BufSize : Word;           {Available size for text}
  79.     MIstruct : MIptr;         {Points to main installation record}
  80.     ComTab : ASCIIZptr;       {Points to terminate command table}
  81.     EOtext : Word;            {Current number of chars in text buffer}
  82.     CursorPos : Word;         {Current cursor position in buffer}
  83.     BlockStart : Word;        {Start of marked block in buffer}
  84.     BlockEnd : Word;          {End of marked block in buffer}
  85.     Status : Word;            {Editor status}
  86.     DataPtr : ^TextBuffer;    {Points to Turbo heap block allocated for text buffer}
  87.   end;
  88.  
  89. const
  90.   {CRT attributes for   normal low blk error}
  91.   MonoArray : AttrArray = ($F, $7, $7, $70);
  92.   BwArray : AttrArray = ($F, $7, $7, $70);
  93.   ColorArray : AttrArray = ($E, $7, $3, $1E);
  94.  
  95.   {--------------------------------------------------------------------------}
  96.  
  97. procedure CRTputFast(x, y : Word; s : string);
  98.   {-Use binary editor services to write a string to the screen}
  99.   {x in 1..25, y in 1..80}
  100.  
  101. function ExpandPath(Fname : string) : string;
  102.   {-Return a complete path using the binary editor services}
  103.  
  104. function InitBinaryEditor
  105.   (var EdData : EdCb;         {Editor control block}
  106.     DataLen : Word;           {Size of binary editor workspace}
  107.     Cx1 : Byte;               {Editor window, upper left x 1..80}
  108.     Cy1 : Byte;               {Editor window, upper left y 1..25}
  109.     Cx2 : Byte;               {Editor window, lower right x 1..80}
  110.     Cy2 : Byte;               {Editor window, lower right y 1..25}
  111.     WaitForRetrace : Boolean; {True for snowy color cards}
  112.     Coptions : Word;          {Initial editor options}
  113.     DefExtension : string;    {Default file extension (must start with period)}
  114.     var ExitCommands;         {Commands to exit editor}
  115.     UserEventProcPtr : Pointer {Pointer to user event handler}
  116.     ) : Word;
  117.  
  118.   {-Initialize the binary editor, returning a status code}
  119.   {
  120.   Status Codes -
  121.   0 = Successful initialization
  122.   1 = Insufficient memory space for text buffer
  123.   }
  124.  
  125. function ReadFileBinaryEditor
  126.   (var EdData : EdCb;
  127.     Fname : string) : Word;
  128.   {-Read a file into the binary editor buffer space, returning a status code}
  129.   {
  130.   Status codes -
  131.     0 = Successful read
  132.     1 = File not found, new file assumed
  133.     2 = File too large to edit
  134.   }
  135.  
  136. procedure ResetBinaryEditor(var EdData : EdCb);
  137.   {-Call the editor reset procedure}
  138.  
  139. function UseBinaryEditor(var EdData : EdCb; StartCommands : string) : Integer;
  140.   {-Edit file, using startcommands, and returning an exitcode}
  141.   {
  142.   Exit codes -
  143.    -1 = Editing terminated with ^KD
  144.     0 = Editing terminated with first user-specified exit command
  145.     1 ...
  146.   }
  147.  
  148. function ModifiedFileBinaryEditor(var EdData : EdCb) : Boolean;
  149.   {-Return true if text buffer was modified during edit}
  150.  
  151. function FileNameBinaryEditor(var EdData : EdCb) : string;
  152.   {-Return the current file pathname of the specified control block}
  153.  
  154. function SaveFileBinaryEditor(var EdData : EdCb; MakeBackup : Boolean) : Word;
  155.   {-Save the current file in the editor text buffer, returning a status code}
  156.   {
  157.   Status codes -
  158.     0 = Successful save
  159.     1 = File creation error
  160.     2 = Disk write error
  161.     3 = Error closing file
  162.   }
  163.  
  164. procedure ReleaseBinaryEditorHeap(var EdData : EdCb);
  165.   {-Release heap space used by a binary editor control block}
  166.  
  167.   {==========================================================================}
  168.  
  169. implementation
  170.  
  171.   {$L BINED}
  172.  
  173.   {Routines internal to ASM code - all called NEAR}
  174.   procedure pAssign(var fromstr, tostr : ASCIIZ); external;
  175.   procedure cCrtPutf(var s : ASCIIZ; r, c : Word); external;
  176.   procedure EditInit(var EdData : EdCb); external;
  177.   procedure EditNew(var EdData : EdCb); external;
  178.   function Editor(var EdData : EdCb) : Integer; external;
  179.  
  180. var
  181.   UserEventAddr : Pointer;
  182.  
  183.   {$L EVENT}
  184.   {$F+}
  185.   procedure EventCheck(pinfo, peventno : Word); external;
  186.     {-Called to activate user background processes}
  187.   {$F-}
  188.  
  189.   function AsciizToStr(a : ASCIIZ) : string;
  190.     {-Convert ASCIIZ to Turbo string}
  191.   var
  192.     s : string;
  193.     slen : Byte absolute s;
  194.  
  195.   begin                       {AsciizToStr}
  196.     slen := 0;
  197.     while a[slen] <> #0 do
  198.       slen := Succ(slen);
  199.     Move(a, s[1], slen);
  200.     AsciizToStr := s;
  201.   end;                        {AsciizToStr}
  202.  
  203.   procedure StrToAsciiz(s : string; var a : ASCIIZ);
  204.     {-Convert a Turbo string into an ASCIIZ}
  205.   var
  206.     slen : Byte absolute s;
  207.  
  208.   begin                       {StrToAsciiz}
  209.     Move(s[1], a, slen);
  210.     a[slen] := #0;
  211.   end;                        {StrToAsciiz}
  212.  
  213.   procedure CRTputFast(x, y : Word; s : String);
  214.     {-Use binary editor services to write a string to the screen}
  215.     {x in 1..25, y in 1..80}
  216.   var
  217.     a : ASCIIZ;
  218.  
  219.   begin                       {CRTputFast}
  220.     {Create ASCIIZ string}
  221.     StrToAsciiz(s, a);
  222.  
  223.     cCrtPutf(a, Pred(y), Pred(x));
  224.   end;                        {CRTputFast}
  225.  
  226.   function ExpandPath(Fname : String) : String;
  227.     {-Return a complete path using the binary editor services}
  228.   var
  229.     fromstr, tostr : ASCIIZ;
  230.  
  231.     function StupCase(s : string) : string;
  232.       {-Uppercase a string}
  233.     var
  234.       i : Word;
  235.  
  236.     begin                     {StupCase}
  237.       for i := 1 to Length(s) do
  238.         s[i] := UpCase(s[i]);
  239.       StupCase := s;
  240.     end;                      {StupCase}
  241.  
  242.   begin                       {ExpandPath}
  243.     {Create ASCIIZ string from input}
  244.     StrToAsciiz(Fname, fromstr);
  245.  
  246.     {Call the binary editor service}
  247.     pAssign(fromstr, tostr);
  248.  
  249.     {Get Turbo string from Asciiz}
  250.     ExpandPath := StupCase(AsciizToStr(tostr));
  251.   end;                        {ExpandPath}
  252.  
  253.   function InitBinaryEditor
  254.    (var EdData : EdCB;
  255.     DataLen : Word;
  256.     Cx1, Cy1, Cx2, Cy2 : Byte;
  257.     WaitForRetrace : Boolean;
  258.     Coptions : Word;
  259.     DefExtension : String;
  260.     var ExitCommands;
  261.     UserEventProcPtr : Pointer
  262.     ) : Word;
  263.  
  264.     {-Initialize the binary editor, returning a status code}
  265.     {
  266.     Status Codes -
  267.     0 = Successful initialization
  268.     1 = Insufficient memory space for text buffer
  269.     }
  270.   var
  271.     nofs, bofs, codelen : Word;
  272.  
  273.   begin                       {InitBinaryEditor}
  274.  
  275.     {Initialize the editor control block}
  276.     with EdData do begin
  277.  
  278.       {Get the data space}
  279.       DataSegLen := DataLen;
  280.       if MaxAvail < DataSegLen then begin
  281.         {Insufficient data space}
  282.         InitBinaryEditor := 1;
  283.         Exit;
  284.       end;
  285.       GetMem(DataPtr, DataSegLen+15);
  286.  
  287.       {Assure data space paragraph aligned}
  288.       if Ofs(DataPtr^) <> 0 then
  289.         DataSeg := Succ(Seg(DataPtr^))
  290.       else
  291.         DataSeg := Seg(DataPtr^);
  292.  
  293.       x1 := Pred(Cx1);
  294.       x2 := Pred(Cx2);
  295.       y1 := Pred(Cy1);
  296.       y2 := Pred(Cy2);
  297.       Options := Coptions;
  298.       GetMem(FileStr, 72);    {Space for max length file string}
  299.       GetMem(Commands, 256);  {Room for 255 bytes of startup keystrokes}
  300.       FillChar(Commands^, 256, #0); {No startup commands right now}
  301.  
  302.       GetMem(Reserved1, 8);      {Null out unused fields}
  303.       FillChar(Reserved1^, 8, #0);
  304.       Reserved2 := nil;
  305.  
  306.       if UserEventProcPtr = nil then
  307.         {Disable event checking}
  308.         Event := nil
  309.       else begin
  310.         {Set up for user event checking}
  311.         Event := Addr(EventCheck);
  312.         UserEventAddr := UserEventProcPtr;
  313.       end;
  314.  
  315.       Buffer := nil;          {Returned by Binary editor after initialization}
  316.       BufSize := 0;           {Returned by Binary editor after initialization}
  317.  
  318.       {Allocate and initialize main installation area}
  319.       New(MIstruct);
  320.       with MIstruct^ do begin
  321.         Ver := 4;
  322.         VerSub := 0;
  323.         VerPatch := 'A';      {4.0A}
  324.         CPUmhz := 5;          {CPU speed in MHz - not critical}
  325.         New(CIstruct);
  326.         with CIstruct^ do begin
  327.           CRTtype := 1;
  328.           CRTx1 := 0;
  329.           CRTy1 := 0;
  330.           CRTx2 := 79;
  331.           CRTy2 := 24;        {Change to 42 for EGA 43 line mode}
  332.           CRTmode := $FF;     {Default screen mode}
  333.           if WaitForRetrace then
  334.             CRTsnow := $FF
  335.           else
  336.             CRTsnow := $0;
  337.           AttrMono := MonoArray;
  338.           AttrBW := BwArray;
  339.           AttrColor := ColorArray;
  340.         end;
  341.         EIstruct := nil;      {Command installation record set by Binary Editor}
  342.         GetMem(DefExt, 8);    {Default file extension}
  343.         StrToAsciiz(DefExtension, DefExt^);
  344.       end;
  345.  
  346.       {Install special exitcommands}
  347.       ComTab := Addr(ExitCommands);
  348.  
  349.       {Position and status variables used by editor}
  350.       EOtext := 0;
  351.       CursorPos := 0;
  352.       BlockStart := 0;
  353.       BlockEnd := 0;
  354.       Status := 0;
  355.  
  356.     end;
  357.  
  358.     {Call the binary editor initialization procedure}
  359.     EditInit(EdData);
  360.  
  361.     {Exit with success code}
  362.     InitBinaryEditor := 0;
  363.  
  364.   end;                        {InitBinaryEditor}
  365.  
  366.   function ReadFileBinaryEditor
  367.    (var EdData : EdCB;
  368.     Fname : String) : Word;
  369.  
  370.     {-Read a file into the binary editor buffer space, returning a status code}
  371.     {
  372.     Status codes -
  373.     0 = Successful read
  374.     1 = File not found, new file assumed
  375.     2 = File too large to edit
  376.     }
  377.   const
  378.     ctrlz = #26;
  379.   var
  380.     f : file;
  381.     fsize : longint;
  382.     zpos, bytesread : Word;
  383.  
  384.   begin                       {ReadFileBinaryEditor}
  385.     with EdData do begin
  386.  
  387.       {Expand the pathname and store it in editor control block}
  388.       Fname := ExpandPath(Fname);
  389.       StrToAsciiz(Fname, FileStr^);
  390.  
  391.       {See whether file exists}
  392.       Assign(f, Fname);
  393.       Reset(f, 1);
  394.       if IOResult <> 0 then begin
  395.         {Couldn't open file, assume a new one}
  396.         EOtext := 0;
  397.         Buffer^[EOtext] := #0;
  398.         ReadFileBinaryEditor := 1;
  399.         Exit;
  400.       end;
  401.  
  402.       {Check the file size}
  403.       fsize := FileSize(f);
  404.       if fsize > BufSize then begin
  405.         {File too big}
  406.         ReadFileBinaryEditor := 2;
  407.         Close(f);
  408.         Exit;
  409.       end;
  410.  
  411.       {Read the file}
  412.       BlockRead(f, Buffer^, fsize, bytesread);
  413.       Close(f);
  414.       EOtext := fsize;
  415.  
  416.       {Scan for control Z in last sector of file}
  417.       if EOtext < 512 then
  418.         zpos := 0
  419.       else
  420.         zpos := EOtext-512;
  421.       while zpos <> EOtext do
  422.         if Buffer^[zpos] = ctrlz then
  423.           EOtext := zpos
  424.         else
  425.           inc(zpos);
  426.       Buffer^[EOtext] := #0;
  427.  
  428.     end;
  429.     {Exit with success code}
  430.     ReadFileBinaryEditor := 0;
  431.   end;                        {ReadFileBinaryEditor}
  432.  
  433.   procedure ResetBinaryEditor(var EdData : EdCB);
  434.     {-Call the editor reset procedure}
  435.  
  436.   begin                       {ResetBinaryEditor}
  437.     EditNew(EdData);
  438.   end;                        {ResetBinaryEditor}
  439.  
  440.   function UseBinaryEditor
  441.    (var EdData : EdCB;
  442.     StartCommands : String) : Integer;
  443.     {-Edit file, using startcommands, and returning an exitcode}
  444.  
  445.   begin                       {UseBinaryEditor}
  446.     {Put the start commands into the editor control block}
  447.     if Length(StartCommands) > 0 then
  448.       Move(StartCommands[1], EdData.Commands^, Length(StartCommands));
  449.  
  450.     {Call the editor}
  451.     UseBinaryEditor := Editor(EdData);
  452.   end;                        {UseBinaryEditor}
  453.  
  454.   function ModifiedFileBinaryEditor(var EdData : EdCB) : Boolean;
  455.     {-Return true if text buffer was modified during edit}
  456.  
  457.   begin                       {ModifiedFileBinaryEditor}
  458.     ModifiedFileBinaryEditor := (EdData.Status and EdStatTextMod) <> 0;
  459.   end;                        {ModifiedFileBinaryEditor}
  460.  
  461.   function FileNameBinaryEditor(var EdData : EdCb) : String;
  462.     {-Return the file name in the specified control block}
  463.  
  464.   begin                       {FileNameBinaryEditor}
  465.     FileNameBinaryEditor := AsciizToStr(EdData.FileStr^);
  466.   end;                        {FileNameBinaryEditor}
  467.  
  468.   function SaveFileBinaryEditor(var EdData : EdCB; MakeBackup : Boolean) : Word;
  469.     {-Save the current file in the editor text buffer, returning a status code}
  470.     {
  471.     Status codes -
  472.     0 = Successful save
  473.     1 = File creation error
  474.     2 = Disk write error
  475.     3 = Error closing file
  476.     }
  477.   var
  478.     f : file;
  479.     Fname : string;
  480.     i, byteswritten : Word;
  481.  
  482.     function Exist(Fname : string; var f : file) : Boolean;
  483.       {-Return true and assigned file handle if file exists}
  484.     var
  485.       i : Word;
  486.     begin                     {Exist}
  487.       Assign(f, Fname);
  488.       Reset(f);
  489.       Exist := (IOResult = 0);
  490.       Close(f);
  491.       {Clear ioresult}
  492.       i := IOResult;
  493.     end;                      {Exist}
  494.  
  495.     procedure MakeBakFile(NewName : string);
  496.       {-Make a backup file}
  497.     var
  498.       nf, bf : file;
  499.       BakName : string;
  500.       DotPos : Byte;
  501.       C : Char;
  502.  
  503.     begin                     {MakeBakFile}
  504.       if Exist(NewName, nf) then begin
  505.         {Workfile already exists, back it up}
  506.  
  507.         {Find position of last period in NewName}
  508.         DotPos := Succ(Length(NewName));
  509.         repeat
  510.           dec(DotPos);
  511.           C := NewName[DotPos];
  512.         until (C = '.') or (C = '\') or (C = ':') or (DotPos = 0);
  513.  
  514.         if (dotpos = 0) or (C <> '.') then
  515.           bakname := newname+'.BAK'
  516.         else
  517.           bakname := Copy(NewName, 1, dotpos)+'BAK';
  518.  
  519.         if Exist(bakname, bf) then
  520.           {Backup already exists, erase it}
  521.           Erase(bf);
  522.         {Rename existing file to backup}
  523.         Rename(nf, bakname);
  524.       end;
  525.     end;                      {MakeBakFile}
  526.  
  527.   begin                       {SaveFileBinaryEditor}
  528.     with EdData do begin
  529.       Fname := AsciizToStr(FileStr^);
  530.       if MakeBackup then
  531.         MakeBakFile(Fname);
  532.       Assign(f, Fname);
  533.       Rewrite(f, 1);
  534.       if IOResult <> 0 then begin
  535.         SaveFileBinaryEditor := 1;
  536.         Close(f);
  537.         i := IOResult;        {Clear ioresult}
  538.         Exit;
  539.       end;
  540.       BlockWrite(f, Buffer^, Succ(EOtext), byteswritten);
  541.       if (byteswritten <> Succ(EOtext)) or (IOResult <> 0) then begin
  542.         SaveFileBinaryEditor := 2;
  543.         Close(f);
  544.         Exit;
  545.       end;
  546.       Close(f);
  547.       if IOResult <> 0 then begin
  548.         SaveFileBinaryEditor := 3;
  549.         Exit;
  550.       end;
  551.       {Reset editor modified bit}
  552.       Status := 0;
  553.       {Success status}
  554.       SaveFileBinaryEditor := 0;
  555.     end;
  556.   end;                        {SaveFileBinaryEditor}
  557.  
  558.   procedure ReleaseBinaryEditorHeap(var EdData : EdCB);
  559.     {-Release heap space used by a binary editor control block}
  560.  
  561.   begin                       {ReleaseBinaryEditorHeap}
  562.     with EdData do begin
  563.       FreeMem(DataPtr, DataSegLen+15);
  564.       FreeMem(FileStr, 72);
  565.       FreeMem(Commands, 256);
  566.       FreeMem(Reserved1, 8);
  567.       Dispose(MIstruct^.CIstruct);
  568.       FreeMem(MIstruct^.DefExt, 8);
  569.       Dispose(MIstruct);
  570.     end;
  571.   end;                        {ReleaseBinaryEditorHeap}
  572.  
  573. end.
  574.