home *** CD-ROM | disk | FTP | other *** search
Prolog Source | 1987-10-20 | 6.3 KB | 207 lines |
-
- /* UNIVDIR.PRO
-
- This routine collects a database of all files in
- all subdirectories on a disk, sorts the filenames, and
- then uses the result to output a formatted, sorted list of
- files to the screen and an ASCII file.
-
- Copyright 1987, by Alex Lane
-
- This program uses modified routines from the Turbo Prolog
- Toolbox, which is Copyright 1987, Borland International.
-
- */
-
-
- domains
- file = f1; f2
- charlist = char *
-
- database
-
- file(string,string,integer,real,string,integer,integer,real,
- integer,integer,integer)
- path(string) /* used to build a pseudo-stack of subdirectories */
- t(integer) /* this functor provides a 'tag' identification */
-
- predicates
- univdir(string)
- post_or_record(string,integer,integer,integer,real,integer,
- integer,real,string)
- tag(integer)
- tokenize_filename(string,string,string)
- list_text(string,charlist) /* (i,o) */
-
- list_text1(string,charlist,string)
- append(charlist,charlist,charlist)
- pretty_out(file,file)
- repeat
-
- goal
- makewindow(1,7,7,"Hard disk directory list sorter",0,0,25,80),
- asserta(t(1)), /* initialize the tag index to 1 */
-
- /* The file TEST.DAT will contain 18-byte records consisting of
- a 12-byte file name, a 4-digit tag identification, and a
- carriage-return-line-feed comhbination
- */
- openwrite(f1,"TEST.DAT"),
-
- /* the argument to univdir() specifies where to START the
- directory search. Examples:
- "" - searches the default disk
- "C:" - searches the C: disk (typically the hard disk)
- "\\PROLOG" - searches the subdirectory \PROLOG on the
- default disk (recall that the '\' character
- must appear twice in a string since it is the
- escape character).
- */
- univdir("C:"),
- closefile(f1),
- retract(t(_)), /* this fella's job is done */
-
- /* we now make a system call to DOS, which will run the
- program RDSRT.COM for us. RDSRT.COM already expects to find
- a file called TEST.DAT in the default directory, and after
- processing, will leave a file called TEST.OUT for us to use
- when control returns to this program.
- */
- system("RDSRT"),
- clearwindow,
- openread(f1,"TEST.OUT"),
-
- /* we will write the sorted hard disk file information to the
- file MYFILES.TXT on the default disk.
- */
- openwrite(f2,"MYFILES.DAT"),
- readdevice(f1),
- writedevice(f2),
- pretty_out(f1,f2),
- readdevice(keyboard),
- writedevice(screen), /* restore the console devices for i/o */
- closefile(f1),
- closefile(f2),
- deletefile("TEST.DAT"),
- deletefile("TEST.OUT"), /* clean up a little before exiting */
- write("\n\nDone. The sorted file listing is in MYFILES.DAT").
-
- /* FINDMATC.PRO is a modified excerpt of the Turbo Toolbox file
- BIOS.PRO Modifications to support file sizes greater 32767.
- */
- include "findmatc.pro"
-
- clauses
-
- /* The univdir() predicate is the workhorse of the the program. It
- calls the Toolbox predicate findmatch() to retrieve filenames. If
- the file name is the name of a subdirectory, the predicate
- post_or_record() asserts the subdirectory name using the path()
- functor. Otherwise, the filename is prepared for sorting and
- asserted through the file() functor.
- */
- univdir(Path) :-
- concat(Path,"\\*.*",SearchSpec),
- findmatch(SearchSpec,63,
- Filename,FileAttr,FileH,FileM,FileY,
- FileMo,FileD,FileSize),
- Filename <> ".", /* ignore the DOS . and .. file entries */
- Filename <> "..",
- post_or_record(Filename,FileAttr,FileH,FileM,FileY,FileMo,
- FileD,FileSize,Path),
- fail. /* we use fail here to force backtracking to
- findmatch() */
-
- /* Once we've exhausted the entries in any given directory, this call
- to univdir() sets us down another path to a new subdirectory by
- retracting a path name through the path() functor.
- */
- univdir(_):-
- retract(path(NewPath)),
- write("!"),
- univdir(NewPath).
-
- /* if we've run out of entries and out of path names, we're done
- scanning the directory on the disk.
- */
- univdir(_):- !.
-
- post_or_record(Name,16,_,_,_,_,_,_,Path):-
- concat(Path,"\\",Halfway),
- concat(Halfway,Name,NewPath),
- asserta(path(NewPath)).
- post_or_record(Name,Attr,Hour,Min,Year,Mo,Day,Size,Path):-
- Attr <> 16,
- write("#"),
- tokenize_filename(Name,File,Ext),
- writedevice(f1),
- tag(A),
- writef("%-8%-4%4\n", File,Ext,A),
- writedevice(screen),
- assertz(file(File,Ext,Attr,Size,Path,Hour,Min,Year,Mo,Day,A)),
- !.
-
- /* I'd like to extract the file and extension parts of the name so
- as to be able to uniformly sort on an 8-char file and 3-char
- extension, with both the file and extension flush left. In other
- words, instead of having names like:
- C.BAT
- FOO.BAR
- DISKDOPE.C
- README
- I'd like to have:
- C .BAT
- FOO .BAR
- DISKDOPE.C
- README .
- */
- tokenize_filename(Name,File,Ext) :-
- list_text(Name,Namelist),
- append(A,['.'|T],Namelist),
- B = [ '.' | T ],
- list_text(File,A),
- list_text(Ext,B).
-
- tokenize_filename(Name,Name,".").
-
- list_text("",[]) :- !.
- list_text(String,[H|T]) :-
- bound(String),
- frontchar(String,H,Rest),
- list_text(Rest,T).
- list_text(String,[H|T]) :-
- bound(H),
- list_text1("",[H|T],String).
-
- list_text1(A,[],A) :- !.
- list_text1(A,[H|T],Out) :-
- str_char(Hs,H),
- concat(A,Hs,AHs),
- list_text1(AHs,T,Out).
-
- tag(N) :-
- retract(t(A)),
- N = A + 1,
- asserta(t(N)), ! .
-
- append([],L,L).
- append([X|L1],L2,[X|L3]) :- append(L1,L2,L3).
-
-
- /* The pretty_out() predicate lets me output a nicely formatted list
- of file information.
- */
- pretty_out(In,Out) :-
- repeat,
- readint(A),
- retract(file(File,Ext,_,Size,Path,Hour,Min,Year,Mo,Day,A)),
- writef("%-8%-4 %6.0f %02:%02 %02-%02-%4 %-24\n",
- File,Ext,Size,Hour,Min,Mo,Day,Year,Path),
- writedevice(screen),
- write("%"),
- writedevice(Out),
- eof(In).
-
- repeat.
- repeat:- repeat.