home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / browse.zip / BROWSE / BROWSE.CMD next >
OS/2 REXX Batch file  |  1995-06-04  |  46KB  |  1,111 lines

  1. /*════════════════════════════════════════════════════════════════════
  2.    REXX BROWSE - View a text file line by line.
  3.    Copyright (c) 1992,1994 Bruce E. Högman. All Rights Reserved.
  4.   ════════════════════════════════════════════════════════════════════*/
  5. BrowseVersion='─V─941015─';
  6. Browse_RC=0;
  7. parse upper arg InFileSpec ProcOpts;
  8. InFileSpec=Strip(InFileSpec);
  9.  
  10. /*════════════════════════════════════════════════════════════════════
  11.    Check to see if all REXX utility functions have been Loaded
  12.    NOTE:  RxFuncQuery tests for REXX load.
  13.   ════════════════════════════════════════════════════════════════════*/
  14. if 0 < RxFuncQuery('SysLoadFuncs') THEN
  15.    DO;
  16.    Call rxfuncadd 'SysLoadFuncs','REXXUTIL','SysLoadFuncs';
  17.    Call SysLoadFuncs;
  18.    END;
  19.  
  20. /*════════════════════════════════════════════════════════════════════
  21.    Obtain source of browse.cmd:  i.e.:  where do we live?
  22.   ════════════════════════════════════════════════════════════════════*/
  23. parse source osname oscmd BrowseCmd
  24.  
  25. /*════════════════════════════════════════════════════════════════════
  26.    Obtain the current video screen size for reset after if needed.
  27.    DEfine keyboard mapping for user interaction.
  28.    Display the short copyright notice.
  29.   ════════════════════════════════════════════════════════════════════*/
  30. Call GetVideoSize; zMaxRow=gMaxRow; zMaxCol=gMaxCol; bVideoReset=0;
  31. if gMaxCol\=80 | gMaxRow\=25 then do; gMaxCol=80; gMaxRow=25;
  32.    '@mode con1 80,25';
  33.    bVideoReset=1;
  34. end;
  35.  
  36. Call Copyright_S;  Call SETKN;
  37. irc=SETLOCAL();  /* Save the CWD, etc. that existed on entry to the REXX */
  38. gCDir=Directory();
  39. if zMaxRow\=gMaxRow | zMaxCol\=gMaxCol then do;
  40.    gMaxRow=zMaxRow; gMaxCol=zMaxCol;
  41.    bVideoReset=1;
  42. end;
  43.  
  44. /*════════════════════════════════════════════════════════════════════
  45.    Define global symbols
  46.   ════════════════════════════════════════════════════════════════════*/
  47. bHexDisplay=0; /* 1: display data in hexadecimal */
  48. OUTR='~'||'fa'x||'fa'x||'fa'x||'fa'x||'fa'x||'fa'x||'fa'x||'fa'x;
  49. INTR=''||'06'x||'07'x||'08'x||'09'x||'0a'x||'0b'x||'0c'x||'0d'x;
  50.  
  51. /*════════════════════════════════════════════════════════════════════
  52.    Set processing options from those specified by the user.
  53.    /A  bShowBlank=1          Show all blank lines, not suppress.
  54.    /B  sFileType=BINARY      Process input file as binary, not text.
  55.    /H  bHelp=1               Display Help Info.
  56.    /I  bDeleteIni=1          Delete all SysIni data.
  57.    /Q  bQuiet=1              Don't display copyright notice.
  58.    /W  bFoldLines=0          Don't fold long lines.
  59.   ════════════════════════════════════════════════════════════════════*/
  60. c=substr(InFileSpec,1,1);
  61. if c='-'|c='/' then do; ProcOpts=InFileSpec ProcOpts; InFileSpec=""; end;
  62. sFileType='TEXT'; if 0<pos('/B',ProcOpts) then sFileType='BINARY';
  63. bShowBlank=0;     if 0<pos('/A',ProcOpts) then bShowBlank=1;
  64. bFoldLines=1;     if 0<pos('/W',ProcOpts) then bFoldLines=0;
  65. bDeleteIni=0;     if 0<pos('/I',ProcOpts) then bDeleteIni=1;
  66. bQuiet=0;         if 0<pos('/Q',ProcOpts) then bQuiet=1;
  67. bHelp=0;
  68.  
  69. if 0<pos('/H',ProcOpts) | 0<pos('/?',ProcOpts) then bHelp=1;
  70.  
  71. if bDeleteIni>0 then do;
  72.    say "You've requested DELETE: of all INI file profile data.";
  73.    say "Are you sure?";
  74.    parse upper pull ReplyStr;
  75.    if 'Y'=substr(ReplyStr,1,1) then do;
  76.       irc=SysIni('USER','BROWSE','DELETE:');
  77.       say 'BROWSE INI profile data deleted.';
  78.    end;
  79. end;
  80.  
  81. TxtEditor='E';
  82. ViewPgm='view'
  83. Call IniParms 'Get';
  84. if DirScrnRow='' | 1>DATATYPE(DirScrnRow,'n') then do;
  85.    DirScrnRow=gMaxRow; TxtScrnRow=gMaxRow;
  86.    DirScrnCol=gMaxCol; TxtScrnCol=gMaxCol;
  87.    bShowBlank=0; if 0<pos('/A',ProcOpts) then bShowBlank=1;
  88.    bFoldLines=1; if 0<pos('/W',ProcOpts) then bFoldLines=0;
  89.    Call GetVidValidModes;
  90.    TxtEditor='E';
  91.    Call IniParms 'PUT';
  92. end;
  93.  
  94. /*════════════════════════════════════════════════════════════════════
  95.    Set BROWSE global values from OS2.INI
  96.    Note:  value is 1st byte - null terminated string.
  97.    Full value is x'3100' for '1', for example.
  98.    We have to strip off trailing null byte.
  99.   ════════════════════════════════════════════════════════════════════*/
  100. TimeFmt=Strip(SysIni('USER','PM_National','iTime'),'t','00'x); /* 0=12hr, 1=234hr */
  101. TimeSep=Strip(SysIni('USER','PM_National','sTime'),'t','00'x); /* single char     */
  102. DateFmt=Strip(SysIni('USER','PM_National','iDate'),'t','00'x); /* 0/1/2: mdy/dmy/ymd */
  103. DateSep=Strip(SysIni('USER','PM_National','sDate'),'t','00'x); /* single char     */
  104. LZero  =Strip(SysIni('USER','PM_National','iLzero'),'t','00'x); /* single char     */
  105.  
  106. /* ================================================================== */
  107. /* Set default colors, call internal IniColors to get or record them. */
  108. /* ================================================================== */
  109. ColrTxtBg=""; Call IniColors 'GET';
  110. if ColrTxtBg="" | ColrTxtBg<30 | ColrTxtBg>47 THEN DO;
  111.    Call COPYRIGHT; /* Display full notice on 1st use of program. */
  112.    ColrTxt=30 /* Black */;         ColrTxtBg=47; /* White*/
  113.    BriteTxt=0; BriteHd=0; ColrHd=30; ColrHdBg=46;
  114.    Call IniColors 'Put';
  115. END;
  116.  
  117. /* ================================================================== */
  118. /* Display help information if the user requested it.                 */
  119. /* ================================================================== */
  120. if bHelp>0 then do;
  121.    Call BROWSE_HELP; Call Copyright; signal COMMON_EXIT;
  122. end;
  123. /* ================================================================== */
  124. /* OK, so does input file exist?  If file named does not exist, take  */
  125. /* user to display of directory.                                      */
  126. /* Note the use of signal below to alter path of program execution.   */
  127. /* Non-structured signal use is flagged.                              */
  128. /* ================================================================== */
  129. If InFileSpec="" then do
  130.    InFileSpec=Directory()||'\*.*';
  131. end;
  132. signal LOOK_DIR;               /* +++++++++++++++++++++++ */
  133.  
  134. BAD_SPEC:;                     /* +++++++++++++++++++++++ */
  135.    signal off syntax;
  136.    say "Bad syntax in file_spec.  I will assume you meant '*.*'";
  137.    irc=SysGetKey('noecho');
  138.    If InFileSpec\="" then do;
  139.       InDrive=FILESPEC('d',InFileSpec);
  140.       InPath =FILESPEC('p',InFileSpec);
  141.       InFileSpec=InDrive||InPath;
  142.    end;
  143.    InFileSpec=InFileSpec||'*.*';
  144.    signal LOOK_DIR;            /* +++++++++++++++++++++++ */
  145.  
  146. BAD_DRIVE:;                    /* +++++++++++++++++++++++ */
  147.    signal off error;  say "Bad drive or path or filename.";
  148.    say "Terminating.";  exit 8;
  149.  
  150. LOOK_DIR:;                     /* +++++++++++++++++++++++ */
  151. InDrive=""; InDrive=FILESPEC('drive',InFileSpec);
  152. drop DList.;
  153. signal on syntax NAME BAD_SPEC;/* +++++++++++++++++++++++ */
  154. If InFileSpec="" then InFileSpec='*.*';
  155. InFullSpec=""; InFullSpec=Stream(InFileSpec,'c','query exists');
  156. signal off syntax;
  157. if InFullSpec="" then do;
  158.    if '..\*.*'=right(InFileSpec,6) then do;
  159.       if '\'=right(InDrive,1) then InFileSpec=InDrive'*.*';
  160.       else
  161.          do
  162.             if '*' <> right(InFileSpec,1) then
  163.                InFileSpec=InDrive'\*.*';
  164.          end
  165.       SIGNAL LOOK_DIR;
  166.    end;
  167.    if 0<pos('\\',InFileSpec) then do;
  168.       xInf=InFileSpec; xInfL=pos('\\',InFileSpec);
  169.       InFileSpec=left(InFileSpec,xInfL)||substr(InFileSpec,xInfL+2);
  170.       signal LOOK_DIR;         /* +++++++++++++++++++++++ */
  171.    end;
  172.    say "No files found for" InFileSpec; Call SysSleep(2);
  173.    irc=SysFileTree(InFileSpec,'DList','BT')
  174.    if DList.0 > 0 then
  175.       do
  176.          parse var Dlist.1 FDate FSize FAttr FName
  177.          if 0 < pos('D',FAttr) then
  178.             do
  179.                filedrive=filespec('d',InFileSpec)
  180.                filepath=filespec('p',InFileSpec)
  181.                filedir=filespec('n',InFileSpec)||'\'
  182.                InFileSpec=filedrive||filepath||filedir
  183.                InFullSpec=InFileSpec||'*.*'
  184.             end
  185.          else
  186.             do
  187.                InFullSpec=filespec('d',InFileSpec)||,
  188.                filespec('p',InFileSpec)||'*.*'
  189.             end
  190.             say 'infullspec='infullspec
  191.             say 'recovery'
  192.       end
  193.    else
  194.       do
  195.          InFileSpec=InDrive||'..\*.*'; signal on error NAME BAD_DRIVE;
  196.          signal LOOK_DIR;            /* +++++++++++++++++++++++ */
  197.       end
  198. end;
  199. signal off error;
  200.  
  201. irc=SysFileTree(InFullSpec,'DList','BT');
  202. InDrive=""; InDrive=FILESPEC('drive',InFileSpec);
  203. InPath="";   InPath=FILESPEC('path',InFileSpec);
  204. InName="";   InName=FILESPEC('name',InFileSpec);
  205. CDir=Directory(InDrive||InPath);
  206. if /*InFullSpec="" |*/ DList.0<1 THEN DO;
  207.    Call Charout , "No files found in " InFullSpec;
  208.    Call SysSleep(2);
  209.    InFileSpec=gCDir;
  210.    if '\'\=right(gCDir,1) then InFileSpec=InFileSpec||'\';
  211.    InFileSpec=InFileSpec||'*.*';
  212.    signal LOOK_DIR;
  213. END;
  214.  
  215. DirFirst=1; CurrDirNr=1;
  216.  
  217. /* ================================================================== */
  218. /* NOTE:  If you signal syntax or errors, do it with "clean" REXX.    */
  219. /* Don't trap errors before you debug the REXX.                       */
  220. /* ================================================================== */
  221. /*signal on error   NAME ERROR_DISPLAY; */
  222. /*signal on novalue NAME ERROR_DISPLAY;*/
  223. /*signal on syntax  NAME ERROR_DISPLAY;*/
  224. signal on halt    NAME ERROR_DISPLAY;
  225.  
  226. /* ================================================================== */
  227. /* Get a map of the used hard drives, A:-Z: and add their names to    */
  228. /* the current list of directories.                                   */
  229. /* ================================================================== */
  230. DriveMap=SysDriveMap('A:');
  231. if DList.0 > 1 then do;
  232.    iNrDirDrives=0;
  233.    DO i=1 to length(DriveMap) by 3;  /* a: b: c: d: e: ... format */
  234.       DriveLtr=substr(DriveMap,i,2);
  235.       DList.0=DList.0+1; DLx=DList.0;
  236.       DList.DLx=DATE('o')'/'substr(TIME(),1,5) '0' '-D---' ' 'DriveLtr'\';
  237.       iNrDirDrives=iNrDirDrives+1;
  238.    end;
  239.    DList.0=DList.0+1; DLx=DList.0;
  240.    DList.DLx=DATE('o')'/'substr(TIME(),1,5) '0' '-D---' ' ..\'
  241.    iNrDirDrives=iNrDirDrives+1;
  242. end;
  243. DirLast=DList.0;
  244.  
  245. /* ================================================================== */
  246. /* Adjust directory listing based on user .ini national values.       */
  247. /* ================================================================== */
  248. FDOffset=9+6+9+2; FLOffset=FDOffset+6; FNOffset=FLOffset+1;
  249. do i=1 to DList.0;
  250.    parse value DList.i with FDT FSize FAttr FName;
  251.    parse value FileDateTime(FDT) with FDate FTime;
  252.    FAttr=TRANSLATE(FAttr,"─","-");
  253.    L=Length(FTime);
  254.    if L<7 then do;
  255.       if L>5 then FTime=' 'FTime;
  256.       else if L<5 then FTime=' 'FTime;
  257.    end;
  258.    DList.i=FDate FTime FORMAT(FSize,8) FAttr FName;
  259. end;
  260.  
  261. /* ================================================================== */
  262. /* Sort the list of files.                                            */
  263. /* ================================================================== */
  264. if DList.0>80 then say "Sorting directory listing of" DList.0 "items.";
  265. iLo=1; iHi=DList.0;
  266. do forever;
  267.    if iLo>iHi then leave;
  268.    i=iLo;
  269.    cLo=substr(DList.iLo,FLOffset,1)||substr(DList.iLo,FDOffset,1)||substr(DList.iLo,FNOffset);
  270.    cHi=substr(DList.iHi,FLOffset,1)||substr(DList.iHi,FDOffset,1)||substr(DList.iHi,FNOffset);
  271.    do forever;
  272.       if i>iHi then leave;
  273.       cX = substr(DList.i,FLOffset,1)||substr(DList.i,FDOffset,1)||substr(DList.i,FNOffset);
  274.       iSwap=0;
  275.       if cX<cLo then do;
  276.          iSwap=1;
  277.          cExch=DList.i; DList.i=DList.iLo; DList.iLo=cExch;
  278.          cLo=substr(DList.iLo,FLOffset,1)||substr(DList.iLo,FDOffset,1)||substr(DList.iLo,FNOffset);
  279.          cX =substr(DList.i,FLOffset,1)||substr(DList.i,FDOffset,1)||substr(DList.i,FNOffset);
  280.       end;
  281.       if cX>cHi then do;
  282.          iSwap=1;
  283.          cExch=DList.i; DList.i=DList.iHi; DList.iHi=cExch;
  284.          cHi=substr(DList.iHi,FLOffset,1)||substr(DList.iHi,FDOffset,1)||substr(DList.iHi,FNOffset);
  285.          cX =substr(DList.i,FLOffset,1)||substr(DList.i,FDOffset,1)||substr(DList.i,FNOffset);
  286.       end;
  287.       if iSwap<1 then i=i+1;
  288.    end;
  289.    iLo=iLo+1; iHi=iHi-1;
  290. end;
  291.  
  292.  
  293. /* ================================================================== */
  294. /* If there is more than one file in list, then display directory     */
  295. /* list and let user choose from the files displayed.                 */
  296. /* ================================================================== */
  297. DISPLAY_FILE_LIST:;
  298. CurrDirNr=1;
  299. CurrDrvName=FILESPEC('d',Stream(InFullSpec,'c','query exists'));
  300. CurrDirName=FILESPEC('p',Stream(InFullSpec,'c','query exists'));
  301. if TxtScrnRow\=DirScrnRow | zMaxRow\=DirScrnRow then do;
  302.    '@mode con1' DirScrnCol','DirScrnRow;
  303.    bVideoReset=1; Call GetVideoSize;
  304. end;
  305.  
  306. /* ================================================================== */
  307. /* DO loop until user does a selection, then we interpret what the    */
  308. /* user selected.                                                     */
  309. /* ================================================================== */
  310. DFg=67-ColrTxt; DBg=87-ColrTxtBg;
  311. gbDirList=0; gbQUIT=0;
  312. ReplyStr="";
  313. DateLine="Directory: "CurrDrvName||CurrDirName;
  314. sListSection='DIR';
  315. if DList.0>1 then do;
  316.    sFileType='TEXT'; /* reset file type */
  317.    if DirLast<gMaxRow & gMaxRow>25 then '@mode con1' gMaxCol','MAX(DirLast,25);
  318.    Call DirDisplay DirFirst; DirLine=1; bDoDisplay=0;
  319.    gbDirList=1;
  320.    do while ReplyStr\="EXIT";
  321.       Call SysCurState 'OFF';
  322.       CurrLineText=SysTextScreenRead(DirLine,0,gMaxCol);
  323.       Call charout ,''DirLine+1';1H'1-BriteTxt';'Dfg';'DBg'm'CurrLineText;
  324.       Call KeyStroke;
  325.       SELECT;
  326.       WHEN ReplyStr="COLR" THEN DO;
  327.          Call ReplyStrCOLR; Call DirDisplay DirFirst;
  328.       END;
  329.       WHEN ReplyStr="CURS" THEN DO;
  330.          SELECT /* Action when ReplyStr=CURS */;
  331.          WHEN Action="BF" then do;
  332.             DirFirst=DirLast; DirLine=1; bDoDisplay=1; end;
  333.          WHEN Action="DN" THEN DO;
  334.             Call NormalText DirLine;
  335.             DirLine=DirLine+1;
  336.             If DirLine>LastScrnLine-1 then do;
  337.                DirLine=1; DirFirst=DirFirst+LinesPerPage;
  338.                if DirFirst>DirLast then DirFirst=DirLast;
  339.                bDoDisplay=1;
  340.             end;
  341.          END;
  342.          WHEN Action="PB" THEN DO;
  343.             DirFirst=DirFirst-LinesPerPage;
  344.             if DirFirst<1 then DirFirst=1;
  345.             DirLine=1; bDoDisplay=1;
  346.          END;
  347.          WHEN Action="PF" THEN DO;
  348.             DirFirst=DirFirst+LinesPerPage;
  349.             if DirFirst>DirLast-1 then DirFirst=DirLast-1;
  350.             DirLine=1; bDoDisplay=1;
  351.          END;
  352.          WHEN Action="TF" then do;
  353.             DirFirst=1; DirLine=1; bDoDisplay=1;
  354.          end;
  355.          WHEN Action="UP" THEN DO;
  356.             Call NormalText DirLine;
  357.             DirLine=DirLine-1;
  358.             if DirLine<1 then do;
  359.                bDoDisplay=1;
  360.                DirFirst=DirFirst-LinesPerPage;
  361.                if DirFirst<1 then do;
  362.                   DirLine=LinesPerPage+DirFirst-1;
  363.                   if DirLine<1 then DirLine=1;
  364.                   DirFirst=1;
  365.                end;
  366.                else DirLine=LinesPerPage;
  367.             end;
  368.          END;
  369.          OTHERWISE NOP;
  370.          END; /* end select */
  371.          if bDoDisplay>0 then do;
  372.             bDoDisplay=0; Call DirDisplay DirFirst;
  373.          end;
  374.       END;
  375.       WHEN ReplyStr="V" then DO;
  376.          signal off error; signal off syntax;
  377.          parse value CurrLineText with FDate FTime FSize FAttr FName;
  378.          ViewPgm FName;
  379.       end;
  380.       WHEN ReplyStr="EDIT" THEN DO;
  381.          signal off error; signal off syntax;
  382.          parse value CurrLineText with FDate FTime FSize FAttr FName;
  383.          TxtEditor FName;
  384.          SIGNAL AFTER_EDIT;
  385.       END;
  386.       WHEN ReplyStr="EXIT" THEN signal COMMON_EXIT;
  387.       WHEN ReplyStr="FILE" THEN SIGNAL FILE_DIALOG;
  388.       WHEN ReplyStr="HEAD" THEN do;
  389.          Call ReplyStrHEAD; Call DirDisplay DirFirst;
  390.       end;
  391.       WHEN ReplyStr="HELP" THEN do;
  392.          Call BROWSE_HELP; Call DirDisplay DirFirst; end;
  393.       WHEN ReplyStr="PARM" THEN Call ReplyStrPARM;
  394.       WHEN ReplyStr="PICK" THEN DO;
  395.          CurrDirNr=DirFirst+DirLine-1; ReplyStr='EXIT';
  396.       end;
  397.       WHEN ReplyStr="SCRN" THEN Call ReplyStrSCRN;
  398.       WHEN ReplyStr="SRCH" THEN Call SrchFile;
  399.       OTHERWISE nop;
  400.       end; /* select */
  401.       if bDoDisplay>0 then do;
  402.          bDoDisplay=0; Call DirDisplay DirFirst;
  403.       end;
  404.    END; /* DO */
  405. END; /* DO */
  406. else gbQUIT=1;
  407.  
  408. /* ================================================================== */
  409. /* Obtain file date, time and format them as user wants.              */
  410. /* ================================================================== */
  411. LISTFILE:;
  412. parse value DList.CurrDirNr with FDate FTime FSize FAttr FName;
  413. FName=Strip(FName);
  414. if 0<pos('D',FAttr) then do;
  415.    gCDir=Directory();
  416.    if FName='..\' then do;
  417.       CDir=Directory()
  418.       CDrv=filespec('d',CDir)
  419.       ParentDir=CDrv||filespec('p',CDir)
  420.       if '\' = right(ParentDir,1) then
  421.          InFileSpec = left(ParentDir,length(ParentDir)-1)
  422.       else InFileSpec=ParentDir
  423.       CDir=Directory('..')
  424.       Signal LOOK_DIR
  425.       CDir=Directory(); iLC=length(CDir);
  426.       if '\' \= right(CDir,1) then CDir=CDir||'\';
  427.       iLC=Length(CDir);  CDir=Left(CDir,iLC-1);
  428.       if ':'=Right(CDir,1) then do;
  429.          CDir=CDir||'\'; InFileSpec=CDir'*.*';
  430.          SIGNAL LOOK_DIR;
  431.       end;
  432.       iPS=Lastpos('\',CDir);
  433.       CDir=Left(CDir,iPS-1); if ':'=right(CDir,1) then CDir=CDir||'\';
  434.       InFileSpec=Directory(CDir);
  435.       if '\'\=right(InFileSpec,1) then InFileSpec=InFileSpec||'\';
  436.       InFileSpec=InFileSpec||'*.*';
  437.       Signal LOOK_DIR;
  438.    end;
  439.    InFileSpec=FName;
  440.    CDir=Directory(InFileSpec);
  441.    if '\'\=right(InFileSpec,1) then InFileSpec=InFileSpec'\';
  442.    InFileSpec=InFileSpec'*.*'; Call SysCls;
  443.    signal LOOK_DIR;
  444. end;
  445. DateLine=FILESPEC('N',FName) FDate FTime FSize;
  446.  
  447. /* ================================================================== */
  448. /* If the file type is not set, test the type of file by reading the  */
  449. /* first 80 bytes.  Scan the 80 byte block, ignoring CRLF, FF         */
  450. /* and count the number of chars less than '20'x.  If the majority    */
  451. /* is less than '20'x then set sFileType='BINARY'.  The test for an   */
  452. /* .exe file is 'MZ' bytes 1+2, then '00'x in 1st 8 positions.        */
  453. /* ================================================================== */
  454. if sFileType\='BINARY' then do;
  455.    xArray=charin(FName,1,80); xCount=0; cCount=0;
  456.    if 'MZ'=substr(xArray,1,2) then do i=3 to 8;
  457.       if '00'x=substr(xArray,i,1) then do;
  458.          sFileType='BINARY'; leave;
  459.       end;
  460.    end;
  461.    else do;
  462.       do i=1 to 80;
  463.          c=substr(xArray,i,1);
  464.          if c<'20'x then xCount=xCount+1; else cCount=cCount+1;
  465.       end;
  466.       if xCount>cCount then sFileType='BINARY';
  467.    end;
  468.    xArray=charin(FName,1,0); drop xArray; /* point file to start */
  469. end;
  470.  
  471. /* ================================================================== */
  472. /* Read the file into storage as array LineArray.                     */
  473. /* Display odometer every 1000 lines.  Capture high-water length.     */
  474. /* Don't collect blank lines in groups of 2 or more.                  */
  475. /* Fold lines at zMaxCol size, continuing a line into the next array  */
  476. /* item.  If the drive is a: | b:, then trip Odo every 100 lines.     */
  477. /* ================================================================== */
  478. if TxtScrnRow\=DirScrnRow | zMaxRow\=TxtScrnRow then do;
  479.    '@mode con1 80,25';
  480.    bVideoReset=1; Call GetVideoSize;
  481. end;
  482. say "Working...";
  483. Drv=FILESPEC('d',FName);
  484. if Drv='A:' | Drv='B:' then OdoTrip=99; else OdoTrip=999;
  485. InBytes=0; LineLast=0; LineFirst=1; Odo=0; MaxLineLen=0;
  486. bBlankLast=0; InBlanks=0; InLines=0;
  487. do forever;
  488.    if 1>Lines(FName) then leave;
  489.    LineLast=LineLast+1; InLines=InLines+1;
  490.    if sFileType='TEXT' then LineArray.LineLast=LINEIN(FName);
  491.    else                     LineArray.LineLast=CHARIN(FName,,80);
  492.    LLen=LENGTH(LineArray.LineLast);
  493.    Odo=Odo+1; InBytes=InBytes+LLen;  MaxLineLen=MAX(MaxLineLen,LLen);
  494.  
  495.    if bFoldLines>0 then do while LLen>zMaxCol;
  496.       LP1=LineLast+1;
  497.       LineArray.LP1=substr(LineArray.LineLast,zMaxCol+1);
  498.       LineArray.LineLast=substr(LineArray.LineLast,1,zMaxCol);
  499.       LineLast=LP1;
  500.       LLen=LENGTH(LineArray.LineLast);
  501.    end;
  502.    else nop;
  503.  
  504.    if bShowBlank<1 then do;
  505.       if LineArray.LineLast="" | LineArray.LineLast=COPIES('20'x,LLen) then do;
  506.          if bBlankLast>0 then do;
  507.             LineLast=LineLast-1; InBlanks=InBlanks+1;
  508.          end;
  509.          bBlankLast=1;
  510.       end;
  511.       else bBlankLast=0;
  512.    end;
  513.    if Odo>OdoTrip THEN DO; Odo=0;
  514.       irc=charout(,"s"InLines "lines," InBytes"/"FSize "bytes," InBlanks "lines dropped," InLines-InBlanks "kept.u");
  515.    END;
  516.  
  517. END; /* do forever */
  518. irc=stream(FName,'c','close');
  519.  
  520. if TxtScrnRow\=DirScrnRow | zMaxRow\=TxtScrnRow then do;
  521.    '@mode con1' TxtScrnCol','TxtScrnRow;
  522.    bVideoReset=1; Call GetVideoSize;
  523. end;
  524. MaxScr=(LineLast+LinesPerPage-1)%LinesPerPage;
  525.  
  526. sListSection='FILE';
  527. ReplyStr="";
  528. if LineLast<gMaxRow & gMaxRow>25 then '@mode con1' gMaxCol','MAX(LineLast,25);
  529. CurrScr=1; Call DataDisplay LineFirst; bDoDisplay=0;
  530. do while ReplyStr\="EXIT";
  531.    Call KeyStroke; parse value SysCurPos() with CRow CCol;
  532.    SELECT;
  533.    WHEN ReplyStr="COLR" THEN DO;
  534.       Call ReplyStrCOLR; Call DataDisplay LineFirst;
  535.    end;
  536.    WHEN ReplyStr="CURS" THEN DO;
  537.       bDoDisplay=1; /* assume we redo display most of the time */
  538.       SELECT /* Action when ReplyStr=CURS */;
  539.       WHEN Action="BF" then  LineFirst=LineLast-1;
  540.       WHEN Action="DN" THEN DO;
  541.          LineFirst=LineFirst+1;
  542.          If LineFirst>LineLast then LineFirst=LineLast;
  543.          else bDoDisplay=0;
  544.       END;
  545.       WHEN Action="PB" THEN DO;
  546.          LineFirst=LineFirst-LinesPerPage;
  547.          if LineFirst<1 then LineFirst=1;
  548.       END;
  549.       WHEN Action="PF" THEN DO;
  550.          LineFirst=LineFirst+LinesPerPage;
  551.          if LineFirst>LineLast-1 then LineFirst=LineLast-1;
  552.       END;
  553.       WHEN Action="TF" then LineFirst=1;
  554.       WHEN Action="UP" THEN DO;
  555.          LineFirst=LineFirst-1;
  556.          If LineFirst<0 then LineFirst=1;
  557.          else bDoDisplay=0;
  558.       END;
  559.       OTHERWISE NOP;
  560.       END;
  561.       if bDoDisplay=1 then call DataDisplay LineFirst;
  562.    END;
  563.    WHEN ReplyStr="EDIT" then do;
  564.       say "Editor:" TxtEditor; irc=sysgetkey();
  565.       TxtEditor FName;
  566.       SIGNAL AFTER_EDIT;
  567.    end;
  568.    WHEN ReplyStr="EXIT" THEN do;
  569.       say ""; leave;
  570.    END;
  571.    WHEN ReplyStr="FILE" THEN SIGNAL FILE_DIALOG;
  572.    WHEN ReplyStr="HEAD" THEN DO;
  573.       Call ReplyStrHEAD; Call DataDisplay LineFirst;
  574.    end;
  575.    WHEN ReplyStr="HELP" THEN DO;
  576.       Call BROWSE_HELP;
  577.    END;
  578.    WHEN ReplyStr="PARM" THEN DO; Call ReplyStrPARM; end;
  579.    WHEN ReplyStr="SCRN" THEN DO; Call ReplyStrSCRN; end;
  580.    WHEN ReplyStr="SRCH" THEN DO;
  581.       Call SrchText; bDoDisplay=1; end;
  582.    OTHERWISE NOP;
  583.    END; /* SELECT */
  584.    Call DataDisplay LineFirst;
  585. END; /* DO */
  586. if gbQUIT<1 then signal DISPLAY_FILE_LIST;
  587. /* ================================================================== */
  588. COMMON_EXIT:;
  589. if bVideoReset>0 then '@mode con1' zMaxCol','zMaxRow;
  590. else Call SysCls;
  591. Call SysCurState 'ON';
  592. exit Browse_RC;
  593.  
  594. /* ================================================================== */
  595. AFTER_EDIT:;
  596.       Call CharOut , "BEdit complete.  Returning to directory.";
  597.       SIGNAL LOOK_DIR;
  598.  
  599. /* ================================================================== */
  600. BROWSE_ERROR:;
  601. say "";
  602. say '*** BROWSE CMD HAS TERMINATED WITH ERROR(S) ***'; Browse_RC=8;
  603. say ''; signal COMMON_EXIT;
  604.  
  605. /* ================================================================== */
  606. BROWSE_HALT:;
  607. say "";
  608. say '*** BROWSE CMD TERMINATED BY USER ***'; Browse_RC=0;
  609. say ''; signal COMMON_EXIT;
  610.  
  611. /* ================================================================== */
  612. BROWSE_HELP:;
  613. '@mode con1 80,25';
  614. irc=CHAROUT(,""ColrHd";"ColrHdBg"m"); iR=1;
  615. Call ScrDisplay iR  "     BROWSE Command HELP INFORMATION" BrowseVersion; iR=iR+1;
  616. Call ScrDisplay iR  "Command Syntax: browse [filespec] [/a] [/b] [/h] [/i] [/w]";iR=iR+1;
  617. Call ScrDisplay iR  "  /a=show blank lines, /b=binary file, /h=help"; iR=iR+1;
  618. Call ScrDisplay iR  "  /i=init saved parms, /w=don't fold long lines."; iR=iR+1;
  619. Call ScrDisplay iR  "Navigation keys:       (Col 1 Notes: +=planned)"; iR=iR+1;
  620. Call ScrDisplay iR  "  Position to top  of file: . . . . . . .  HOME"; iR=iR+1;
  621. Call ScrDisplay iR  "  Position to bottom of file:               END"; iR=iR+1;
  622. Call ScrDisplay iR  "  Scroll to next     page:  . . . . . . .  PgDn"; iR=iR+1;
  623. Call ScrDisplay iR  "  Scroll to previous page:                 PgUp"; iR=iR+1;
  624. Call ScrDisplay iR  "  HELP display: . . . . . . . . . . . . . .  F1"; iR=iR+1;
  625. Call ScrDisplay iR  "  Save Current parameters:                   F2"; iR=iR+1;
  626. Call ScrDisplay iR  "  Change text foreground color: . . . . . .  F5"; iR=iR+1;
  627. Call ScrDisplay iR  "  Change text background color:              F6"; iR=iR+1;
  628. Call ScrDisplay iR  "  Change head foreground color: . . . . . .  F7"; iR=iR+1;
  629. Call ScrDisplay iR  "  Change head background color:              F8"; iR=iR+1;
  630. Call ScrDisplay iR  "+ Toggle Hexadecimal data display:[future]   F9"; iR=iR+1;
  631. Call ScrDisplay iR  "  Set screen size & select editor:          F10"; iR=iR+1;
  632. Call ScrDisplay iR  "  Toggle NOFOLD of long lines:              F11"; iR=iR+1;
  633. Call ScrDisplay iR  "  Select higlighted directory/file:       ENTER"; iR=iR+1;
  634. Call ScrDisplay iR  "  EDIT file selected or being browsed         E"; iR=iR+1;
  635. Call ScrDisplay iR  "  Set new directory/file to browse            F"; iR=iR+1;
  636. Call ScrDisplay iR  "+ Search for text (partially implemented)     S"; iR=iR+1;
  637. Call ScrDisplay iR  "+ View .HLP file using VIEW                   V"; iR=iR+1;
  638. Call ScrDisplay iR  "  EXIT/END:         ALT-F4 / F3           / ESC"; iR=iR+1;
  639. Call ScrDisplay iR  "*** Hit any key to continue ***";
  640. irc=SysGetKey('noecho');
  641. '@mode con1' gMaxCol','gMaxRow;
  642. return 0;
  643.  
  644. /*════════════════════════════════════════════════════════════════════*/
  645. COPYRIGHT:;
  646.    if bQuiet>0 then return;
  647.    Call Copyright_S;
  648.    TAB="     ";
  649.    say tab TAB"This program is published as shareware by the author, who ";
  650.    say tab TAB"ascribes to the principles and practices of the Association";
  651.    say tab TAB"of Shareware Professionals. If you use this program, please";
  652.    say tab TAB"support the shareware principles by registering this program";
  653.    say tab TAB"with the author for a suggested fee of $7. The author will";
  654.    say tab TAB"send you the next published version at no additional cost.";
  655.    say tab TAB"You may copy this program freely and distribute it as long";
  656.    say tab TAB"as there is no fee charged for this program by itself.";
  657.    say " B";
  658.    say TAB TAB TAB TAB TAB" Bruce Eric Högman";
  659.    say TAB TAB TAB TAB TAB" 1338 Avocado Isle";
  660.    say TAB TAB TAB TAB TAB" Fort Lauderdale  FL 33315-1344";
  661.    irc=SysGetKey('noecho');
  662.    return;
  663.  
  664. /* ================================================================== */
  665. Copyright_S:;
  666.    if bQuiet>0 then return;
  667.    Call charout ,'';
  668.    call charout ,'';
  669.    call charout ,'7H';
  670.    call charout ,' ┌───────────────────────────────────────────┐';
  671.    call charout ,'7H';
  672.    call charout ,' │ Bruce Eric Högman Copyright (C) 1992,1994 │';
  673.    call charout ,'7H';
  674.    call charout ,' │            All Rights Reserved.           │';
  675.    call charout ,'7H';
  676.    call charout ,' │ Compuserve: 72050,1327                    │';
  677.    call charout ,'7H';
  678.    call charout ,' └───────────────'BrowseVersion'──────────────────┘';
  679.    call charout ,'BD';
  680.    call SysSleep(1);
  681.    return;
  682.  
  683. /*════════════════════════════════════════════════════════════════════*/
  684.       LineArray.LineLast=TRANSLATE(CHARIN(FName,,80),OUTR,INTR);
  685. DataDisplay:;
  686.    Call SysCurState 'off';
  687.    if LineFirst < 1 then LineFirst=1;   j=LineFirst;
  688.    CurrScr = (LineFirst + LinesPerPage - 1) % LinesPerPage;
  689.    NrScrRow = Min(LinesPerPage,LineLast);
  690.    EndNr = MIN(LineLast,LineFirst + LinesPerPage -1);
  691.    MaxScr = (LineLast + LinesPerPage -1) % LinesPerPage;
  692.    if sFileType='BINARY' then sBin='/B';   else sBin='';
  693.    if bFoldLines=0 then sNF='/W';   else sNF='';
  694.    Call ScrDisplay 1 DateLine "-"  CurrScr"/"MaxScr" pages. Lines" LineFirst"-"EndNr "of" LineLast"."sBin||sNF;
  695.    if bHexDisplay<1 then;
  696.       do i=1 to NrScrRow;
  697.          if j>LineLast then LineArray.j="";
  698.          Call ScrDisplay i+1 TRANSLATE(LineArray.j,OUTR,INTR);
  699.          j=j+1;
  700.       END;
  701.    else do /* Translate data into vertical hex */ ;
  702.       iLastHexLine=(NrScrRow%3); HexLine1=""; HexLine2="";
  703.       do i=1 to iLastHexLine by 3;
  704.          if j>LineLast then leave; j=j+1;
  705.          Call ScrDisplay i+1 TRANSLATE(LineArray.j,OUTR,INTR);
  706.          HexDataLine=LineArray.j;
  707.          Call HexTranslate;
  708.          Call ScrDisplay i+2 HexLine1;
  709.          Call ScrDisplay i+3 HexLine2;
  710.       end;
  711.    END;
  712.    return;
  713.  
  714. /*════════════════════════════════════════════════════════════════════*/
  715. DirDisplay:;
  716.    Call SysCurState 'ON';  if DirFirst<1 then DirFirst=1;
  717.    CurrScr = (DirFirst + LinesPerPage - 1) % LinesPerPage;
  718.    NrScrRow = Min(LinesPerPage,DirLast);  j=DirFirst;
  719.    EndNr = MIN(DirLast,DirFirst + LinesPerPage - 1);
  720.    MaxScr = (DirLast + LinesPerPage - 1) % LinesPerPage;
  721.    Call ScrDisplay 1 DateLine "-"  CurrScr"/"MaxScr" pages. Files" DirFirst"-"EndNr "of" DirLast".";
  722.    do i=1 to NrScrRow;
  723.       if j > DirLast then DList.j="";
  724.       Call ScrDisplay i+1 DList.j; j=j+1;
  725.    END;
  726.    return;
  727.  
  728. /*════════════════════════════════════════════════════════════════════*/
  729. ERROR_DISPLAY:;
  730.   Call SysCurState 'ON';
  731.   if condition('c')='HALT' then signal BROWSE_HALT;
  732.   say 'BROWSE SIGNAL TRAP at line'SIGL;
  733.   say condition('c') condition('i') condition('d') condition('s');
  734.   signal BROWSE_ERROR;
  735.  
  736. /*════════════════════════════════════════════════════════════════════*/
  737. /* returns filedate filetime  given format: yy/mm/dd/hh/mm */
  738. /*════════════════════════════════════════════════════════════════════*/
  739. FileDateTime:;
  740.    parse arg FDT;
  741.    TODHr=substr(FDT,10,2); TODMn=substr(FDT,13,2);
  742.    YY=substr(FDT,1,2); MM=substr(FDT,4,2); DD=substr(FDT,7,2);
  743.    SELECT;
  744.       WHEN TimeFmt='0' THEN DO;
  745.          AMPM='AM';
  746.          if TODHr>11 THEN DO;
  747.             AMPM='PM'; if TODHr>12 then TODHr=TODHr-12;
  748.          END;
  749.          if length(TODHr)<2 then if Lzero=1 then TODHr="0"TODHr;
  750.          UTime=TODHr||TimeSep||TODMn||AMPM;
  751.       END;
  752.       WHEN TimeFmt='1' THEN DO;
  753.          TODHr=TODHr+0;
  754.          if length(TODHr)<2 then if Lzero=1 then TODHr="0"TODHr;
  755.          UTime=TODHr||TimeSep||TODMn;
  756.       END;
  757.       OTHERWISE NOP;
  758.    END; /* select */
  759.    SELECT;
  760.       WHEN DateFmt='0' then  UDate=MM||DateSep||DD||DateSep||YY;
  761.       WHEN DateFmt='1' then  UDate=DD||DateSep||MM||DateSep||YY;
  762.       WHEN DateFmt='2' then  UDate=YY||DateSep||MM||DateSep||DD;
  763.       OTHERWISE nop;
  764.    END; /* select */
  765.    return UDate UTime;
  766.  
  767. /*════════════════════════════════════════════════════════════════════*/
  768. FILE_DIALOG:
  769.    dTxt='Enter new filespec: [d:] [\path] filename (wild cards OK)';
  770.    Call WinOpen dTxt;
  771.    call charout , "uB>";
  772.    Call SysCurState 'ON';  /* display text cursor */
  773.    parse upper pull InFileSpecTst;
  774.    Call SysCurState 'OFF'; /* hide    text cursor */
  775.    if InFileSpecTst\="" then InFileSpec=InFileSpecTst;
  776.    SIGNAL LOOK_DIR;
  777.  
  778. /*════════════════════════════════════════════════════════════════════*/
  779. GetVideoSize:;
  780.    parse value SysTextScreenSize() with gMaxRow gMaxCol;
  781.    LinesPerPage=gMaxRow-2;
  782.    return;
  783.  
  784. /*════════════════════════════════════════════════════════════════════*/
  785. /* Notes on video modes set using mode command:                       */
  786. /* Modes with lines less than 25 produce larger characters and may be */
  787. /* useful to sight-impaired users.                                    */
  788. /*════════════════════════════════════════════════════════════════════*/
  789. GetVidValidModes:;
  790.    Call SysCls;
  791.    say "About to test video for valid mode range using 80-col display.";
  792.    say "Hit any key to continue...";
  793.    irc=SysGetKey(); Call SysCls; bVidError=0;
  794.    ValidVideoModes="";
  795.    do i=60 to 14 by -1;
  796.       bVidError=0; call on error name erropt;
  797.       '@mode con1 80,'i;
  798.       if bVidError<1 then do;
  799.          ValidVideoModes=ValidVideoModes i;
  800.       end;
  801.    end;
  802.    '@mode con1 80,25';
  803.    Say 'valid video modes are: 80x';
  804.    say ValidVideoModes; irc=SysGetKey(); Call SysCls;
  805.    irc=SysIni('USER','BROWSE','ValidVideoModes',ValidVideoModes);
  806.    call off error;
  807.    return;
  808.    erropt: bVidError=1; return;
  809.  
  810. /*════════════════════════════════════════════════════════════════════*/
  811. /* Translate line of data into hexadecimal for vertical display.      */
  812. /* Returns HexLine1 and HexLine2.                                     */
  813. /* Input is HexDataLine.                                              */
  814. /*════════════════════════════════════════════════════════════════════*/
  815. HexTranslate:;
  816.    HexLine1=""; HexLine2="";
  817.    do ix=1 to LENGTH(HexDataLine);
  818.       sHex=c2x(substr(HexDataLine,ix,1));
  819.       HexLine1=HexLine1||substr(sHex,1,1);
  820.       HexLine2=HexLine2||substr(sHex,2,1);
  821.    end;
  822.    return;
  823.  
  824. /*════════════════════════════════════════════════════════════════════*/
  825. IniColors:;
  826.    parse upper arg Operation;
  827.    if Operation="GET" THEN DO;
  828.       ColrTxtBg =SysIni('USER','BROWSE','ColorTextBg');
  829.       ColrHdBg  =SysIni('USER','BROWSE','ColorHeadBg');
  830.       ColrTxt   =SysIni('USER','BROWSE','ColorText');
  831.       ColrHd    =SysIni('USER','BROWSE','ColorHead');
  832.       BriteTxt  =SysIni('USER','BROWSE','BriteText');
  833.       BriteHd   =SysIni('USER','BROWSE','BriteHead');
  834.    END;
  835.    else do;
  836.       irc       =SysIni('USER','BROWSE','ColorTextBg',ColrTxtBg);
  837.       irc       =SysIni('USER','BROWSE','ColorHeadBg',ColrHdBg);
  838.       irc       =SysIni('USER','BROWSE','ColorText',ColrTxt);
  839.       irc       =SysIni('USER','BROWSE','ColorHead',ColrHd);
  840.       irc       =SysIni('USER','BROWSE','BriteText',BriteTxt);
  841.       irc       =SysIni('USER','BROWSE','BriteHead',BriteHd);
  842.    END;
  843.    return;
  844.  
  845. /*════════════════════════════════════════════════════════════════════*/
  846. IniParms:;
  847.    parse upper arg Operation;
  848.    if Operation="GET" THEN DO;
  849.       DirScrnRow     =SysIni('USER','BROWSE','DirScrnRow');
  850.       DirScrnCol     =SysIni('USER','BROWSE','DirScrnCol');
  851.       TxtEditor      =SysIni('USER','BROWSE','TxtEditor');
  852.       TxtScrnRow     =SysIni('USER','BROWSE','TxtScrnRow');
  853.       TxtScrnCol     =SysIni('USER','BROWSE','TxtScrnCol');
  854.       bShowBlank     =SysIni('USER','BROWSE','bShowBlank');
  855.       bFoldLines     =SysIni('USER','BROWSE','bFoldLines');
  856.       ValidVideoModes=SysIni('USER','BROWSE','ValidVideoModes');
  857.    END;
  858.    else do;
  859.       irc       =SysIni('USER','BROWSE','DirScrnRow',DirScrnRow);
  860.       irc       =SysIni('USER','BROWSE','DirScrnCol',DirScrnCol);
  861.       irc       =SysIni('USER','BROWSE','TxtEditor',TxtEditor);
  862.       irc       =SysIni('USER','BROWSE','TxtScrnRow',TxtScrnRow);
  863.       irc       =SysIni('USER','BROWSE','TxtScrnCol',TxtScrnCol);
  864.       irc       =SysIni('USER','BROWSE','bShowBlank',bShowBlank);
  865.       irc       =SysIni('USER','BROWSE','bFoldLines',bFoldLines);
  866.       irc=SysIni('USER','BROWSE','ValidVideoModes',ValidVideoModes);
  867.    END;
  868.    return;
  869.  
  870. /*════════════════════════════════════════════════════════════════════*/
  871. KeyStroke:;
  872. do forever;
  873.    parse value SysCurPos() with VidRow VidCol;
  874.    Action=""; key=SysGetKey('noecho');
  875.    if c2x(key)='1B' THEN DO; ReplyStr="EXIT"; Action="ES"; return; END;
  876.    kv=c2d(key);
  877.    if c2x(key)='E0' THEN DO;
  878.       kv=1000; key=SysGetkey('noecho'); kv=kv+c2d(key);
  879.    END;
  880.    else do;
  881.       if kv=0 THEN DO; kv=1000; key=SysGetKey('noecho'); kv=kv+c2d(key);
  882.       END;
  883.    END;
  884.    if "K." \= substr(k.kv,1,2) THEN DO;
  885.       SELECT;
  886.       when k.kv="UCURS"  THEN DO; ReplyStr="CURS"; Action="UP"; return; END;
  887.       when k.kv="DCURS"  THEN DO; ReplyStr="CURS"; Action="DN"; return; END;
  888.       when k.kv="HOME"   THEN DO; ReplyStr="CURS"; Action="TF"; return; END;
  889.       when k.kv="END"    THEN DO; ReplyStr="CURS"; Action="BF"; return; END;
  890.       when k.kv="INS"    THEN DO; ReplyStr="CURS"; Action="HI"; return; END;
  891.       when k.kv="DEL"    THEN DO; ReplyStr="CURS"; Action="LO"; return; END;
  892.       when k.kv="PGUP"   THEN DO; ReplyStr="CURS"; Action="PB"; return; END;
  893.       when k.kv="PGDN"   THEN DO; ReplyStr="CURS"; Action="PF"; return; END;
  894.       when k.kv="EDIT"   THEN DO; ReplyStr="PICK"; Action="ED"; return; END;
  895.       when k.kv="V"      THEN DO; ReplyStr="PICK"; Action="VW"; return; END;
  896.       when k.kv="ENTER"  THEN DO; ReplyStr="PICK"; Action="LV"; return; END;
  897.       when k.kv="F1"     THEN DO; ReplyStr="HELP"; Action="F1"; return; END;
  898.       when k.kv="F2"     THEN DO; ReplyStr="PARM"; Action="SV"; return; END;
  899.       when k.kv="F3"     THEN DO; ReplyStr="EXIT"; Action="F3"; return; END;
  900.       when k.kv="ALT-F4" THEN DO; ReplyStr="EXIT"; Action="QU"; return; END;
  901.       when k.kv="F5"     THEN DO; ReplyStr="COLR"; Action="FG"; return; END;
  902.       when k.kv="F6"     THEN DO; ReplyStr="COLR"; Action="BG"; return; END;
  903.       when k.kv="F7"     THEN DO; ReplyStr="HEAD"; Action="FG"; return; END;
  904.       when k.kv="F8"     THEN DO; ReplyStr="HEAD"; Action="BG"; return; END;
  905.       when k.kv="F9"     THEN DO; ReplyStr="SCRN"; Action="HX"; return; END;
  906.       when k.kv="F10"    THEN DO; ReplyStr="SCRN"; Action="SZ"; return; END;
  907.       when k.kv="F11"    THEN DO; ReplyStr="SCRN"; Action="NF"; return; END;
  908.       when k.kv="F"      THEN DO; ReplyStr="FILE"; Action="IO"; return; END;
  909.       when k.kv="S"      THEN DO; ReplyStr="SRCH"; Action="IO"; return; END;
  910.       when k.kv="E"      THEN DO; ReplyStr="EDIT"; Action="EX"; return; END;
  911.       otherwise nop;
  912.       END;
  913.    END;
  914.    if Action \= "" then return;
  915. END;
  916. return;
  917.  
  918. /*════════════════════════════════════════════════════════════════════*/
  919. NormalText:;
  920.    parse arg CurrScrnLn;
  921.    CurrLineText=SysTextScreenRead(CurrScrnLn,0,gMaxCol);
  922.    Call charout ,''CurrScrnLn+1';1H'BriteTxt';'ColrTxt';'ColrTxtBg'm'CurrLineText;
  923.    return;
  924.  
  925. /*════════════════════════════════════════════════════════════════════*/
  926. PullScreenSize:;
  927.    parse arg VTTxt;
  928.    Call WinOpen VTTxt;
  929.    irc=charout(,'uB >s __ __ <u');
  930.    Call SysCurState 'ON'; /* display text cursor */
  931.    parse pull iCol iRow;
  932.    Call SysCurState 'OFF'; /* display text cursor */
  933.    if 0<DATATYPE(iCol,'n') & 0<DATATYPE(iRow,'n') then do;
  934.       if 0<pos(iRow,ValidVideoModes) then do;
  935.          if 0<iCol & 0<iRow then do;
  936.             '@mode con1' iCol','iRow;
  937.             call GetVideoSize;
  938.          end;
  939.       end;
  940.       else do;
  941.          Call SysCls;
  942.          say 'Video mode' iCol','iRow '(col,row) invalid.'
  943.          say "Valid video modes are";
  944.          say ValidVideoModes;
  945.          irc=SysGetKey();
  946.       end;
  947.    end;
  948.    drop VTTxt tTLen iWinCol iWinRow tColrTxt tColrTxtBg iCol iRow;
  949.    return;
  950.  
  951. /*════════════════════════════════════════════════════════════════════*/
  952. WinOpen:;
  953.    parse arg VTTxt;
  954.    parse value SysTextScreenSize() with iRow iCol;
  955.    tTLen=LENGTH(VTTxt);
  956.    iWinCol=(iCol-tTLen)%2; iWinRow=iRow%3;
  957.    tColrTxt=37-ColrTxt+30; tColrTxtBg=47-ColrTxtBg;
  958.    irc=charout(,''tColrTxt';'tColrTxtBg'm');
  959.    do i=1 to iWinRow;
  960.       irc=charout(,''iWinRow+i';'iWinCol'H'copies(' ',tTLen+2));
  961.    end;
  962.    i=iWinRow%2;
  963.    irc=charout(,''iWinRow+i';'iWinCol+1'H');
  964.    irc=charout(,'s'VTTxt);
  965.    return;
  966.  
  967. /*════════════════════════════════════════════════════════════════════*/
  968. PullTxtEditor:;
  969.  
  970. /*════════════════════════════════════════════════════════════════════*/
  971. ReplyStrCOLR:;
  972.    if Action="FG" THEN DO;
  973.       ColrTxt=ColrTxt+BriteTxt; if ColrTxt=38 then ColrTxt=30;
  974.       if BriteTxt=0 then BriteTxt=1; else BriteTxt=0;
  975.    END;
  976.    else do; ColrTxtBg=ColrTxtBg+1; if ColrTxtBg=48 then ColrTxtBg=40; END;
  977.    bDoDisplay=1;
  978.    return;
  979.  
  980. ReplyStrHEAD:;
  981.    if Action="FG" THEN DO;
  982.       ColrHd=ColrHd+BriteHd; if ColrHd=38 then ColrHd=30;
  983.       if BriteHd=0 then BriteHd=1; else BriteHd=0;
  984.    END;
  985.    else do; ColrHdBg=ColrHdBg+1; if ColrHdBg=48 then ColrHdBg=40; end;
  986.    Return;
  987.  
  988. ReplyStrPARM:;
  989.    Call IniColors 'Put'; Call IniParms 'Put';
  990.    '@mode con1 80,25';  Call Copyright;
  991.    irc=charout(,"HCurrent Values Saved");
  992.    Call SysSleep(1); '@mode con1 ' gMaxCol','gMaxRow;
  993.    bDoDisplay=1;
  994.    Return;
  995.  
  996. ReplyStrSCRN:; /* Input:  sListSection=DIR/FILE */
  997.    SELECT;
  998.    WHEN Action="SZ" then do;
  999.       dTxt='Enter \DIR list screen size as Cols Rows or 0 to Quit';
  1000.       Call PullScreenSize dTxt; drop dTxt;
  1001.       DirScrnRow=gMaxRow; DirScrnCol=gMaxCol;
  1002.       if sListSection='FILE' then  Call DataDisplay LineFirst;
  1003.       else                         Call DirDisplay DirFirst;
  1004.       fTxt='Enter FILE list screen size as Cols Rows or 0 to Quit';
  1005.       Call PullScreenSize fTxt; drop fTxt;
  1006.       TxtScrnRow=gMaxRow; TxtScrnCol=gMaxCol;
  1007.       if sListSection='DIR' then '@mode con1' DirScrnCol','DirScrnRow;
  1008.       if sListSection='FILE' then  Call DataDisplay LineFirst;
  1009.       else                         Call DirDisplay DirFirst;
  1010.       eTxt='Enter full path and filename of editor program';
  1011.       Call WinOpen eTxt;
  1012.       call charout ,"uB";
  1013.       Call SysCurState 'ON'; /* display text cursor */
  1014.       parse upper pull TxtEditor;
  1015.       Call SysCurState 'OFF'; /* display text cursor */
  1016.       if '.EXE'\=Right(TxtEditor,4) then do;
  1017.          TstEditName=TxtEditor||'.EXE';
  1018.          FExists=Stream(TstEditName,'c','query exists');
  1019.          if FExists\="" then do;
  1020.             TxtEditor=TstEditName; say " OK";
  1021.          end;
  1022.          else do;
  1023.             TstEditName=TxtEditor||'.COM';
  1024.             FExists=Stream(TstEditName,'c','query exists');
  1025.             if FExists\="" then do;
  1026.                TxtEditor=TstEditName; say " OK";
  1027.             end;
  1028.             else do;
  1029.                call charout ,"BDUnable to locate" TxtEditor;
  1030.                irc=sysgetkey();
  1031.                TxtEditor='E';
  1032.             end;
  1033.          end;
  1034.       end;
  1035.       else do;
  1036.          FExists=Stream(TxtEditor,'c','query exists');
  1037.          if FExists="" then do;
  1038.             call charout ,"BDUnable to locate" TxtEditor;
  1039.             irc=sysgetkey(); TxtEditor='E';
  1040.          end;
  1041.          else say " OK";
  1042.       end;
  1043.    end;
  1044.    WHEN Action="NF" then do;
  1045.       if bFoldLines=0 then bFoldLines=1; else bFoldLines=0;
  1046.    end;
  1047.    WHEN Action="HX" then do;
  1048.       bHexDisplay=\bHexDisplay;
  1049.    end;
  1050.    OTHERWISE NOP;
  1051.    END; /* select */
  1052.    bDoDisplay=1;
  1053.    Return;
  1054.  
  1055. /*════════════════════════════════════════════════════════════════════*/
  1056. ScrDisplay:;
  1057. parse arg RowNr LineData;
  1058. if RowNr<2 THEN DO; SFgColr=ColrHd; Bright=BriteHd; SBgColr=ColrHdBg; END;
  1059. else do; SFgColr=ColrTxt; Bright=BriteTxt; SBgColr=ColrTxtBg; END;
  1060. irc=CHAROUT(,""RowNr";1H"Bright";"SFgColr";"SBgColr"m"LineData""RowNr";1H");
  1061. LastScrnLine=RowNr;
  1062. return;
  1063.  
  1064.  
  1065. /*════════════════════════════════════════════════════════════════════*/
  1066. SrchFile:;
  1067.    dTxt="Search text at directory level is not yet implemented.";
  1068.    Call WinOpen dTxt;
  1069.    call charout , "uBHit any key to return";
  1070.    irc=sysgetkey(); bDoDisplay=1;
  1071.    return;
  1072.  
  1073. /*════════════════════════════════════════════════════════════════════*/
  1074. SrchText:;
  1075.    dTxt="Enter text to search for.  Case is not important.";
  1076.    Call WinOpen dTxt; call SysCurState 'ON';
  1077.    call charout , "uB>";
  1078.    parse pull SrchString; Call SysCurState 'OFF';
  1079.    Call SysFileSearch SrchString,FName,'Srch','n';
  1080.    if Srch.0<1 then do;
  1081.       Call DataDisplay;
  1082.       dTxt="No lines found with text" SrchString;
  1083.       Call WinOpen dTxt;
  1084.       call charout , "uBCHit any key to continue.";
  1085.       irc=SysGetKey();
  1086.    end;
  1087.    else do;
  1088.       CDir=Directory(); if '\' \= right(CDir,1) then CDir=CDir'\';
  1089.       TmpFile=SysTempFileName(CDir'Browse.???');
  1090.       do i=1 to Srch.0;
  1091.          irc=Lineout(TmpFile,Srch.i);
  1092.       end;
  1093.       irc=Stream(TmpFile,'c','close');
  1094.       '@CALL' BrowseCmd TmpFile '/Q';
  1095. /*    call browse TmpFile '/Q';*/
  1096.       'ERASE' TmpFile;
  1097.    end;
  1098.    return;
  1099. /*════════════════════════════════════════════════════════════════════*/
  1100. SETKN:;
  1101. k.70='F'; k.102='F';k.83='S'; k.115='S'; k.69='E'; k.101='E';
  1102. k.118='V';
  1103. k.1059='F1'; k.1060='F2'; k.1061='F3';   k.1062='F4';   k.1063='F5';
  1104. k.1064='F6'; k.1065='F7';    k.1066='F8';   k.1067='F9';   k.1068='F10';
  1105. k.1071='HOME'; k.1072='UCURS'; k.1073='PGUP'; k.1075='LCURS';
  1106. k.1077='RCURS';
  1107. k.1081='PGDN';
  1108. k.1079='END'; k.1080='DCURS'; k.1082='INS';  k.1083='DEL';
  1109. k.1107='ALT-F4'; k.1133='F11';   k.1134='F12';  k.13='ENTER';  return;
  1110.  
  1111.