home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 13 / CDA13.ISO / cdactual / demobin / share / program / Pascal / ADD10.ZIP / ADD.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1988-07-15  |  11.7 KB  |  546 lines

  1. { FreeWare - Just don't modify and re-distribute.
  2.  
  3.   Randy Crawford
  4.   12 Taft Ct., Suite.110
  5.   Rockville, MD  20850
  6.   301-424-6892
  7.  
  8.   ADD - Alphabetized Double-wide Directory utility.
  9.   Requires Turbo Pascal 4.0.
  10.   Sort help displayed using '/' on command line }
  11.  
  12. Program ADD;
  13.  
  14. Uses CRT, DOS;
  15.  
  16. Const
  17.     Numfiles = 300;
  18.  
  19. Type
  20.     Filename = array [1..numfiles] of string [60];
  21.     Filesize = string [40];
  22.     Strng2   = string [2];
  23.  
  24. VAR
  25.     Page:   integer;
  26.     FileCount: integer;              { total # of files }
  27.     Count2: integer;
  28.     Srec:   SEARCHREC;
  29.     Path:   STRING[40];
  30.     FirstDir: String[40];
  31.     Drive1: Strng2;
  32.     Pfile1: string[60];
  33.     Pfile2: string[60];
  34.     ATTR:   BYTE;
  35.     YEAR:   string[4];
  36.     MONTH:  strng2;
  37.     DAY:    strng2;
  38.     dt:     datetime;
  39.     hour:   strng2;
  40.     min:    strng2;
  41.     name:   filesize;
  42.     size:   filesize;
  43.     files:  filename;
  44.     decpos: integer;
  45.     tsize:  longint;
  46.     tot:    boolean;
  47.     ext:    boolean;
  48.     dat:    boolean;
  49.     siz:    boolean;
  50.     help:   boolean;
  51.     Reverse: boolean;
  52.     REGS:   REGISTERS;
  53.     diff:   integer;
  54.     left:   integer;
  55.     Lines:  integer;
  56.     pivot:  integer;
  57.     group:  integer;
  58.     scan1:  integer;
  59.     scan2:  integer;
  60.     extend: string[3];
  61.     parmstr: string;
  62.     letter:  char;
  63.     ScrollNum: integer;
  64.     DiskLeft:  longint;
  65.     DLeft:     filesize;
  66.     DiskSpace: longint;
  67.     DSpace:    filesize;
  68.     RetKey:    char;
  69.     Colour:    word;
  70.  
  71. Procedure Flip;      { reverse order of array }
  72. Var
  73.     Count: integer;
  74.     Pivot: integer;
  75.     Offset: integer;
  76.     Hold : string[60];
  77.     LastFile: integer;
  78. Begin
  79.     Pivot := FileCount DIV 2;
  80.     LastFile := FileCount + 1;
  81.     if (Pivot * 2) > FileCount then    { if Filecount=7, Pivot=3 }
  82.         Pivot := Pivot - 1;
  83.  
  84.     For Count := 1 to Pivot DO
  85.     BEGIN
  86.         Hold := Files [Count];
  87.         Offset := LastFile - Count;
  88.         Files [Count] := Files [Offset];
  89.         Files [Offset] := Hold;
  90.     END;
  91. End;
  92.  
  93. Procedure GetChar (VAR Key: char);
  94. BEGIN
  95.     gotoxy (80, 25);
  96.     key := CHR(0);
  97.     repeat
  98.         Key := ReadKey;
  99.     until key <> chr(0);
  100. END;
  101.  
  102. Procedure Caps (VAR CAPS: STRING);    { set string to all caps }
  103. VAR
  104.     count: integer;
  105.     long:  integer;
  106. begin
  107.     long := length (caps);
  108.     for count := 1 to long do
  109.         IF (ord (caps [count]) > 96) and (ord (caps [count]) < 123) then
  110.             caps [count] := chr (ord (caps [count]) - 32);
  111. end;
  112.  
  113. Procedure Comma (VAR numstr: filesize);
  114. VAR
  115.     dot   : integer;
  116.     plc   : integer;
  117.     tens  : real;
  118.     number: real;
  119. begin
  120.     val (numstr, number, dot);
  121.     dot  := pos ('.', numstr);
  122.     if dot = 0 then
  123.         dot := length (numstr) + 1;
  124.     plc  := 3;
  125.     tens := 1000;
  126.     While (copy (numstr, 1, 1) = ' ') and (number >= tens) DO
  127.         begin
  128.             insert (',', numstr, dot - plc);
  129.             delete (numstr, 1, 1);
  130.             tens := tens * 1000;
  131.             plc := plc + 4;
  132.         end;
  133. end;
  134.  
  135. Procedure Fpad (VAR strng : filesize);
  136. VAR
  137.     plc: integer;
  138. BEGIN
  139.     plc := pos ('.', strng);
  140.     While (plc > 0) and (plc < 9) DO
  141.     Begin
  142.         insert (' ', strng, plc);
  143.         plc := pos ('.', strng);
  144.     End;
  145.     plc := length (strng);
  146.     While (plc < 12) DO
  147.     Begin
  148.         strng := strng + ' ';
  149.         plc := length (strng);
  150.     End;
  151.     strng[9] := ' ';
  152. END;
  153.  
  154. Procedure Npad (VAR strng : strng2);
  155. BEGIN
  156.     if copy (strng, 1, 1) = ' ' then
  157.         begin
  158.             strng := copy (strng, 2, 1);
  159.             insert ('0', strng, 1)
  160.         end;
  161. END;
  162.  
  163. Procedure Attributes;   { check for DIR / set size }
  164. BEGIN
  165.     if ((srec.attr and 16) = 16) then
  166.         size := chr(178)+chr(177)+' DIR '+chr(177)+chr(178)
  167.     else
  168.         BEGIN
  169.             str (srec.SIZE:8, size);
  170.             comma (size);
  171.             size := ' ' + size;
  172.         END;
  173. END;    { attributes }
  174.  
  175. Procedure CheckParams;
  176. Var
  177.     spc : integer;
  178.     count: integer;
  179.     chekpath: string [12];
  180. BEGIN
  181.     path := '*.*';
  182.     tot := false;
  183.     ext := false;
  184.     dat := false;
  185.     siz := false;
  186.     help:= false;
  187.     Reverse:= False;
  188.  
  189.     if (paramcount > 0) then
  190.     BEGIN
  191.             { set path }
  192.         chekpath := paramstr(1);
  193.  
  194.         if pos (':', chekpath) = 2 then
  195.             drive1 := copy(chekpath,1,2)
  196.         else
  197.             drive1 := '';
  198.  
  199.         if pos('/',ChekPath) <> 0 then
  200.             ChekPath := '*.*';
  201.  
  202.         if (paramstr (1) = '.') then
  203.             chekpath := '*.*';
  204.  
  205.         if (paramstr (1) = '..') then
  206.             chekpath := '..\*.*';
  207.  
  208.         if (paramstr (1) = '...') then
  209.             chekpath := '...\*.*';
  210.  
  211.         if (pos (':', chekpath) <> 0) and (length (chekpath) = 2) then
  212.             chekpath := chekpath + '*.*';      { A: to  A:*.*}
  213.  
  214.         if (pos ('*',chekpath) <> 0) and (pos ('.', chekpath) = 0) then
  215.             chekpath := paramstr(1) + '.*';
  216.  
  217.         FindFirst (chekpath, attr, srec);  { file or subdirectory? }
  218.  
  219.         if (doserror = 0) then   { TRADE is file, \TRADE is DIR }
  220.         BEGIN
  221.             count := 2;
  222.             if (pos ('.', chekpath) = 0) and ((srec.attr and 16) = 16) then
  223.                     path := chekpath + '\*.*'  { entire directory }
  224.             else
  225.                 path := chekpath             { a file mask found }
  226.         END
  227.         else
  228.         begin
  229.             if copy (paramstr (1), 1, 1) = '/' then
  230.                 count := 1                   { not a file mask }
  231.             else
  232.             begin
  233.                 count := paramcount + 1;     { a file mask not found }
  234.                 path := paramstr (1);
  235.             end
  236.         end;
  237.  
  238.             { parse sort order sub string }
  239.         parmstr := '';    { concat sub-string }
  240.         Count := 1;
  241.         while (count <= paramcount) do
  242.         begin
  243.             parmstr := parmstr + paramstr (count);
  244.             count := count + 1;
  245.         end;
  246.  
  247.         caps (parmstr);
  248.  
  249.         if (POS ('/T', PARMSTR) <> 0) then
  250.             TOT := TRUE;
  251.         if (POS ('/S', PARMSTR) <> 0) then
  252.             SIZ := TRUE;
  253.         IF (POS ('/E', PARMSTR) <> 0) THEN
  254.             EXT := TRUE;
  255.         IF (POS ('/D', PARMSTR) <> 0) THEN
  256.             DAT := TRUE;
  257.         IF (POS ('/R', PARMSTR) <> 0) THEN
  258.             Reverse := TRUE;
  259.  
  260.         if (pos ('/', PARMSTR) <> 0) AND (DAT = FALSE) AND
  261.             (TOT = FALSE) AND (EXT = FALSE) AND (SIZ = FALSE)
  262.                 AND (REVERSE = FALSE) THEN
  263.             HELP := TRUE;
  264.  
  265.     END;
  266. END;     { path }
  267.  
  268. Procedure Quicksort (Lo, Hi: integer);
  269.     Procedure Sort (L, R: integer);
  270.     var
  271.         I, J: integer;
  272.         X, Y: STRING [50];
  273.     begin
  274.         I := L;
  275.         J := R;
  276.         X := files [(L+R) DIV 2];
  277.         repeat
  278.             while files [I] < X do
  279.                 I := I + 1;
  280.                 while X < files [J] do
  281.                     J := J - 1;
  282.                 if I <= J then
  283.                     begin
  284.                         Y := files [I];
  285.                         files [I] := files [J];
  286.                         files [J] := Y;
  287.                         I := I+1;
  288.                         J := J-1;
  289.                     end;
  290.         until I > J;
  291.         if L < J then sort (L, J);
  292.         if I < R then sort (I, R);
  293.     end;
  294. BEGIN    { quicksort }
  295.     Sort (Lo, Hi);
  296. END;     { quicksort }
  297.  
  298. Procedure SetCurs (CURSCN : LONGINT);
  299. Var
  300.     regs : registers;
  301. begin
  302.     REGS.AX := $100;
  303.     REGS.CX := CURSCN;  { $2020 elims cursor, $0607 restores for EGA amd mono }
  304.     INTR ($10, REGS);
  305. end;
  306.  
  307. Procedure Truncate;
  308. VAR
  309.     DelAmt: integer;
  310. Begin
  311.     Pfile1 := files [count2 + group];
  312.     Pfile2 := files [count2 + group + diff];
  313.     DelAmt := 1;
  314.     if (SIZ = true) then
  315.         DelAmt := DelAmt + 9;
  316.  
  317.     if (DAT = true) then
  318.         DelAmt := DelAmt + 5;
  319.  
  320.     if (EXT = true) then
  321.         DelAmt := DelAmt + 3;
  322.  
  323.     delete (pfile1, 1, DelAmt);
  324.     delete (pfile2, 1, DelAmt);
  325. End;
  326.  
  327. Procedure ScrollUp (ScLines: integer);
  328. Begin
  329.     If Page > 0 then
  330.         ScLines := ScLines + 1;
  331.  
  332.     if ScLines >= 25 then
  333.         ScLines := 25
  334.     else
  335.         ScLines := ScLines + 1;
  336.  
  337.     REGS.AX := $600 + ScLines;
  338.     REGS.BX := Colour * 256; { BH is scroll attribute - prob 7 gray }
  339.     REGS.CX := $0000;        { top row , left col }
  340.     REGS.DX := $184F;        { bot row, right col }
  341.  
  342.     INTR ($10, REGS);
  343.  
  344.     If (Page > 0) and (ScLines > 1) then
  345.         ScLines := ScLines - 1;
  346.  
  347.     ScLines := MEM [$0:$451] + 1 - ScLines;
  348.  
  349.     if Sclines < 1 then
  350.         ScLines := 1;
  351.  
  352.     gotoxy (1, ScLines);
  353.  
  354.     If (Page > 0) and (ScLines > 1) then
  355.         Writeln ('───────────────────────────────────────┼───────────────────────────────────────');
  356. End;
  357.  
  358. Procedure ShowFiles;       { prints list of files }
  359. BEGIN
  360.         Lines := FileCount div 2;
  361.         if Lines <> (FileCount / 2) then
  362.             Lines := Lines + 1;
  363.         diff := lines;
  364.  
  365.         if (diff > 25) then diff := 25;
  366.         count2 := 1;
  367.         left  := Lines;
  368.         group := 0;
  369.         pivot := count2 + 25;
  370.  
  371.         ScrollNum := (MEM [$0:$451] + Left) - 24;
  372.  
  373.         if (ScrollNum >= 0) then
  374.             ScrollUp (ScrollNum);
  375.  
  376.         while (count2 <= Lines) and (RetKey <> Chr(27)) DO
  377.         begin
  378.             truncate;
  379.  
  380.             write (pfile1 + ' │ ' + pfile2);
  381.             count2 := count2 + 1;
  382.  
  383.             if (count2 = pivot)  then
  384.             begin
  385.                 GETCHAR (RetKey);
  386.                 if (RetKey <> chr(27)) then
  387.                 begin
  388.                     Page := Page + 1;
  389.                     left := left - 25;
  390.                     diff := left;
  391.  
  392.                     if (left < 25) then
  393.                         left := left + 1;
  394.                     ScrollUp (Left);
  395.  
  396.                     if diff > 25 then diff := 25;
  397.                     group := group + 25;
  398.                     pivot := count2 + 25;
  399.                 end;
  400.             end
  401.             else
  402.                 Writeln;
  403.         end;
  404.     end;
  405.  
  406. Procedure Getfiles;
  407. BEGIN
  408.     for FileCount := 1 to numfiles do
  409.         files [FileCount] := '';
  410.     TSIZE := 0;
  411.  
  412.     FindFirst (path, attr, srec);
  413.     FileCount := 0;
  414.  
  415.     while (DosError = 0) and (FileCount < numfiles) do
  416.     begin
  417.         if (copy (srec.name, 1, 1) <> '.') then
  418.         BEGIN
  419.             FileCount := FileCount + 1;
  420.             if (srec.attr and 16) <> 16 then
  421.                 tsize := tsize + srec.size;
  422.  
  423.             if (TOT = False) then         { 17 long }
  424.             Begin
  425.                 UNPACKTIME (srec.TIME, dt);
  426.                 str (DT.YEAR:4, year);
  427.                 year := copy (year, 3, 2);
  428.                 str (DT.MONTH:2, month);
  429.                 str (DT.DAY:2, day);
  430.                 npad (day);
  431.                 str (dt.min:2, min);
  432.                 npad (min);
  433.                 str (dt.hour:2, hour);
  434.                 name := srec.name;
  435.                 fpad (name);
  436.                 attributes;
  437.  
  438.                 if (EXT = true) then      { +3 }
  439.                 begin
  440.                     extend := copy (name, 10, 3);
  441.                     if (srec.attr and 16) = 16 then
  442.                         extend := chr(0)+chr(0)+chr(0);  { directory }
  443.                     name := extend + name;
  444.                 end;
  445.  
  446.                 if (DAT = true) then      { +5 }
  447.                     name := chr(255 xor (dt.year-1900)) + chr(255 xor dt.month)
  448.                      + chr(255 xor dt.day) + chr(255 xor dt.hour)
  449.                      + chr(255 xor dt.min) + name;
  450.  
  451.                 if (SIZ = true) then      { +9 }
  452.                 begin
  453.                     if (srec.attr and 16) = 16 then
  454.                         name := '         ' + name
  455.                     else
  456.                         name := size + name;
  457.                 end;
  458.  
  459.                 if (srec.attr and 16) = 16 then    { +1 }
  460.                     name := chr(0) + name  { directory }
  461.                 else
  462.                     name := chr(32) + name;
  463.  
  464.                 Files [FileCount] := name+size+'  '+MONTH+'.'+DAY+'.'+YEAR+'  '+hour+':'+min;
  465.             End;
  466.         END;
  467.         FindNext (srec);
  468.     end;
  469. END;
  470.  
  471. Function Cut (letters: string): string;
  472. begin
  473.     while copy (letters,1,1) = ' ' DO
  474.         letters := copy (letters, 2, 80);
  475.     while copy (letters, length (letters), 1) = ' ' DO
  476.         letters := copy (letters, 1, length (letters) - 1);
  477.     Cut := letters;
  478. end;
  479.  
  480. BEGIN        { main }
  481.     RetKey := ' ';
  482.     Page := 0;
  483.     attr := $37;
  484.     Drive1 := '';
  485.  
  486.     GetDir (0,FirstDir);        { set current directory }
  487.     CheckParams;       { look for sort specs, file mask, drive and directory }
  488.  
  489.     if (help = true) then
  490.     begin
  491.         writeln;
  492.         writeln ('      Flags are:');
  493.         writeln;
  494.         writeln ('          /D  Sort by date and time.');
  495.         writeln ('          /E  Sort by extension.');
  496.         writeln ('          /S  Sort by size.');
  497.         Writeln ('          /R  Reverse sort order.');
  498.         writeln;
  499.         writeln ('          /T  No sort:  Total bytes on disk for matching files.');
  500.     end
  501.     else
  502.     begin
  503.         if Drive1 <> '' then
  504.             Chdir (Drive1);
  505.  
  506.         DiskLeft  := DiskFree (0);
  507.         DiskSpace := DiskSize (0);
  508.  
  509.         GetFiles;
  510.  
  511.         IF (TOT = False) and (FileCount <> 0) THEN
  512.         BEGIN            { set color for scroll }
  513.             Colour := MEM [0:$449];
  514.             If (Colour <> 7) then
  515.                 Colour := MEM [$B800:3841];  { FROM BOTTOM LINE ON SCREEN }
  516.  
  517.             QuickSort (1, FileCount);
  518.             If (Reverse = True) then   { reverse sorted order }
  519.                 Flip;
  520.                 ShowFiles;
  521.         END;
  522.  
  523.         if (RetKey <> Chr(27)) then
  524.         begin
  525.             if (FileCount <> 0) then
  526.             begin
  527.                 str (tsize:11, size);
  528.                 comma (size);
  529.                 str (diskleft:12, dleft);
  530.                 comma (dleft);
  531.                 str (diskspace:12, dspace);
  532.                 comma (dspace);
  533.                 WRITE ('        ',SIZE,' bytes in ',FileCount,' files ... ',Cut(DLeft),' free of ',Cut(DSpace),'.');
  534.                 { volume label ? }
  535.             end
  536.             else
  537.                 WRITE ('                      No files found using '+path+' mask.');
  538.  
  539.             if (count2 = (pivot - 1)) then
  540.                 GETCHAR (RetKey);
  541.  
  542.             Chdir (FirstDir);
  543.         end;
  544.     end;
  545. END.
  546.