program emptytest(empty,notempty,output); (* emptytest: Test for file empty Dr. Thomas D. Schneider National Institutes of Health National Cancer Institute Center for Cancer Research Nanobiology Program Molecular Information Theory Group Frederick, Maryland 21702-1201 toms@ncifcrf.gov permanent email: toms@alum.mit.edu (use only if first address fails) http://www.ccrnp.ncifcrf.gov/~toms/ *) const (* begin module version *) version = 2.03; (* of emptytest.p 2005 Sep 13 2005 Sep 15, 2.03: emptytest works here but FAILS inside alist. the alist version WORKS. LOCK THIS VERSION! 2005 Sep 15, 2.02: get version of emptyfile from alist that works. 2005 Sep 13, 2.01: upgrade documentation 2005 Sep 13, 2.00: use counting characters - works! 2005 Jan 27, 1.00: origin - failed because counting lines does not work. *) updateversion = 1.00; (* defines lowest acceptable current parameter file *) (* end module version *) (* begin module describe.emptytest *) (* name emptytest: Test for file empty synopsis emptytest(empty: in, notempty: in, output: out) files empty: an empty file. There should be no characters in this file. You can create it under Unix with: echo -n "" > empty or if there is none before, touch empty notempty: any file with at least one character You can create it under Unix with: echo -n "some text" > empty description The GPC compiler has a serious bug in it. When one resets an empty file, it is not eof. In contrast, the p2c translator/compiler works perfectly. So this program provides a routine, emptyfile, that tests for eof and responds properly. The method is to count the actual number of characters in the file. examples Results from p2c: ---- emptytest: ------------------------- empty file is eof ......... OK! notempty file is not eof .. OK! ---- test emptyfile: lines = 0 chars = 0 empty file is empty lines = 0 chars = 1 notempty file is not empty ------------------------------------------ So p2c works perfectly. Results from GPC: ---- emptytest: ------------------------- empty file is not eof ..... OOPS! notempty file is not eof .. OK! ---- test emptyfile: lines = 1 chars = 0 empty file is empty lines = 0 chars = 1 notempty file is not empty ------------------------------------------ So GPC failed to detect the eof correctly and thought that there was one line in the empty file. FORTUNATELY counting characters works. There are at least three ways to test for a file in Unix: ls -l wc file These can be used to PROVE that the file is empty. A script, emptyunixtests, can be used to check the files. The results are: version = 1.00 of emptyunixtests 2005 Sep 13 tests for empty file: % ls -l empty -rw------- 1 toms delila 0 Jan 27 2005 empty % wc empty 0 0 0 empty % file empty empty: empty file ------ tests for notempty file: % ls -l notempty -rw------- 1 toms delila 29 Sep 13 19:04 notempty % wc notempty 1 5 29 notempty documentation see also {GPC discussion, patch given:} http://www.gnu-pascal.de/crystal/gpc/en/mail11285.html {GPC Gnu Pascal Compiler:} http://www.ccrnp.ncifcrf.gov/~toms/pascalgpc.html {P2C Pascal Translator and Compiler:} http://www.ccrnp.ncifcrf.gov/~toms/pascalp2c.html {The alist program was messed up by this bug:} http://www.lecb.ncifcrf.gov/~toms/delila/alist.html {Three tests for files named empty and notempty determine if the files are empty or not:} emptyunixtests {empty file:} empty {not empty file:} notempty author Thomas Dana Schneider bugs technical notes *) (* end module describe.emptytest *) var empty, (* file used by this program *) notempty: (* file used by this program *) text; (* file used by this program *) (* begin module strictemptyfile *) (* this is a STRICT version that fails *) function strictemptyfile(var afile: text): boolean; (* Count characters in a file to determine if it is empty to get around a GPC bug that eof file can't be detected when a file is empty. Fortunately this is fast for large files because the count stops once a single character is seen. Dr. Thomas D. Schneider National Institutes of Health National Cancer Institute Center for Cancer Research Nanobiology Program Molecular Information Theory Group Frederick, Maryland 21702-1201 toms@ncifcrf.gov permanent email: toms@alum.mit.edu (use only if first address fails) http://www.ccrnp.ncifcrf.gov/~toms/ *) var lines: integer; (* count of lines in the file *) chars: integer; (* count of characters in the file *) ch: char; (* a character in the file *) begin reset(afile); lines := 0; chars := 0; while (not eof(afile)) and (chars < 1) do begin if eoln(afile) then begin lines := succ(lines); readln(afile); end else begin read(afile,ch); chars := succ(chars); end end; if chars = 0 then strictemptyfile := true else strictemptyfile := false; writeln(output,'lines = ',lines:1); writeln(output,'chars = ',chars:1); end; (* end module strictemptyfile *) (* begin module LOCKemptyfile *) function emptyfile(var afile: text): boolean; (* Count characters in a file to determine if it is empty to get around a GPC bug that eof file can't be detected when a file is empty. Fortunately this is fast for large files because the count stops once a single or a few characters are seen. A single character will not do unfortunately because GPC will give an '*' for an empty file. So the test is for having 4 or fewer characters. This is not great, but it only means that the names have to be at least 5 characters long. Dr. Thomas D. Schneider National Institutes of Health National Cancer Institute Center for Cancer Research Nanobiology Program Molecular Information Theory Group Frederick, Maryland 21702-1201 toms@ncifcrf.gov permanent email: toms@alum.mit.edu (use only if first address fails) http://www.ccrnp.ncifcrf.gov/~toms/ *) const debugging = false; boundary = 2; (* one needs at least this many characters for a file to be considered 'non empty'. *) var lines: integer; (* count of lines in the file *) chars: integer; (* count of characters in the file *) ch: char; (* a character in the file *) begin reset(afile); lines := 0; chars := 0; while (not eof(afile)) and (chars < boundary) do begin if eoln(afile) then begin lines := succ(lines); readln(afile); end else begin read(afile,ch); if debugging then begin writeln(output,'emptyfile: ord(ch) = ',ord(ch)); writeln(output,'emptyfile: ch = ', ch ); end; chars := succ(chars); end end; if chars < boundary then emptyfile := true else emptyfile := false; if debugging then begin writeln(output,'emptyfile: lines = ',lines:1); writeln(output,'emptyfile: chars = ',chars:1); if chars < boundary then writeln(output,'emptyfile: chars < boundary, ', chars:1, '<', boundary:1) else writeln(output,'emptyfile: chars < boundary, ', chars:1, '>=', boundary:1); end; end; (* end module LOCKemptyfile *) (* begin module emptytest.themain *) procedure themain(var empty, noempty: text); (* the main procedure of the program *) begin writeln(output,'emptytest ',version:4:2); writeln(output,'---- emptytest: -------------------------'); writeln(output,'---- test eof():'); reset(empty); if eof(empty) then writeln(output, 'empty file is eof ....... OK!') else writeln(output, 'empty file is not eof ..... OOPS!'); reset(notempty); if eof(notempty) then writeln(output, 'notempty file is eof ...... OPS!') else writeln(output, 'notempty file is not eof ....... OK!'); writeln(output,'---- test emptyfile():'); if emptyfile(empty) then writeln(output, 'empty file is empty ..... OK!') else writeln(output, 'empty file is not empty ... OOPS!'); if emptyfile(notempty) then writeln(output, 'notempty file is empty ... OOPS!') else writeln(output, 'notempty file is not empty ..... OK!'); writeln(output,'------------------------------------------'); end; (* end module emptytest.themain *) begin themain(empty, notempty); end.