[Back to TEXTFILE SWAG index] [Back to Main SWAG index] [Original]
{
From: "Scott F. Earnest" <tiobe+@CMU.EDU>
About a month ago, I posted a program called "SmartConvert" which does auto-
matic conversions between DOS and UNIX format text files.
Unfortunately, there were a couple problems with the code I posted I wasn't
aware of:
1.) While debugging, I accidentally removed the code which called the
procedures to check that the files existed. Hopefully nobody's
gotten in trouble by overwriting files they didn't mean to. . . .
2.) S . . . L . . . O . . . W . . . ! I clocked a large file (~650K)
both ways, and got a time over 7 minutes. In this version, I
reassigned the text file buffers to 8K, and got much better times.
I've also added an overwrite switch to ignore the output file.
And could the kind soul(s) who donated the previous version to SWAG please
make sure this replaces the old version in the next upgrade? Thanks!
þ Done! - Kerry þ
}
program SConvert;
{Smart-converts UN*X/DOS format files
Usage: sconvert infile [outfile] [/u | /d] [/o]
/u -- force output to UNIX (LF only)
/d -- force output to DOS (CR/LF)
/o -- Overwrite output file if it exists (for batch support)
-- or --
sconvert /? (-?, /h, -h, /H, and -H analogous)
for help message
This program is capabable of having its output piped, provided
it is the first in the pipeline. Doesn't do well as an inter-
mediary pipe section.
Written by Scott F. Earnest, Aug 1993
Original version: 30 Aug 1993
Updated versions: 9 May 1994 (Added force flags.)
9 Jun 1994 (Bug fix, added /o flag.)
This version uses 8K input/output buffers instead of the default 128-byte
text buffers. The result is a performance of over 250% (only noticeable
with large files). Untyped files turned out to be worthless here--they
performed worse than text files, believe it or not.
Unless I come up with a phenomenal improvement, this is the last version
I plan to post.
}
uses Crt;
const
CR = chr(13); {Carriage Return}
LF = chr(10); {Line Feed}
type
sys = (dos,unix,bad); {system identifier}
{Note to people who make upgrades--if you
need the DOS unit, you'll have to modify
this variable so that "DOS" isn't a label.}
fbuf = array [0 .. 8191] of char;
var
sysID : sys; {system identifier for case branch}
infile, outfile : string; {input/output files}
force : sys; {what mode to work in}
overwrite : boolean; {(don't) check if outfile exists}
ibuf, obuf : fbuf; {increase text buffers}
function exist (filename : string) : boolean;
{Check if a file exists or not
returns: true --> file exists
false --> file non-existent}
var
openfile : text;
errcode : integer;
begin
{$I-} {Turn off error-checking}
assign (openfile, filename);
reset (openfile);
{$I+} {Turn it back on}
errcode := IOResult; {Get error code}
if errcode <> 0 then {There's an error if non-zero}
exist := false {So flag that it doesn't exist.}
else
begin
close (openfile); {Otherwise, close file}
exist := true; {Flag that it does exist}
end;
end;
function selectyn : boolean;
{Get a yes/no single-keypress response
returns: true --> yes response, y or Y
false --> no response, n or N}
var
getchar : char; {Need something to read into}
begin
while KeyPressed do {Clean keyboard buffer}
getchar := ReadKey;
repeat {Get a key until it's a (Y)es or (N)o.}
getchar := ReadKey;
getchar := upcase (getchar);
until (getchar in ['Y', 'N']);
writeln (getchar); {Print the response}
case getchar of {Tell it what it should return}
'Y' : selectyn := true;
'N' : selectyn := false;
end;
end;
procedure help (badflag : boolean);
{brief message if command format was abused}
begin
writeln ('SmartConvert, Written by Scott F. Earnest -- v1.4 -- 9 Jun 1994');
writeln;
if badflag then
begin
writeln ('Invalid flag.');
writeln;
end;
writeln ('Usage');
writeln (' sconvert infile [outfile] [/d | /u] [/o]');
writeln;
writeln (' /d -- convert input to DOS format');
writeln (' /u -- convert input to UNIX format');
writeln (' /o -- unconditionally overwrite output');
writeln (' (for batch files or writing to devices)');
halt (1);
end;
procedure incheck (filename : string);
{Make sure source exists, if specified}
begin
if not (exist (filename)) then
begin
writeln ('Source file does not exist!');
halt (3);
end;
end;
procedure outcheck (filename : string);
{Make sure target does NOT exist, if specified, allow overwrite}
var
select : boolean;
begin
if exist (filename) and (filename <> '') then
begin
write ('Target file exists! Overwrite? [y/n] ');
select := selectyn;
case select of
true : ;
false : halt (4);
end;
end;
end;
function checktype (readfile : string) : sys;
var
FileCheck : text;
checkvar : sys;
CROk, LFOk : boolean;
ReadBuf : char;
begin
CROk := False;
LFOk := False; {Init flags.}
checkvar := bad; {Assume that type isn't known.}
assign (FileCheck, readfile);
reset (FileCheck);
while (not eof(FileCheck)) and (not CROk) and (not LFOk) do
begin {Look for CR or LF}
read (FileCheck, ReadBuf);
if ReadBuf = CR then {CR found?}
begin
CROk := True; {If yes, set the CR flag.}
Read (FileCheck, ReadBuf); {and get next char}
if ReadBuf = LF then {next one a LF?}
LFOk := True; {Flag it as found.}
if CROk and LFOk then {So is it CR/LF?}
begin
checktype := dos; {If yes, specify DOS, and exit.}
close (FileCheck);
exit;
end;
end;
if ReadBuf = LF then {Found a LF?}
begin
checktype := unix; {If yes, assume unix.}
close (FileCheck); {Close and exit.}
exit;
end;
end;
if checkvar = bad then {If there was a problem:}
begin
writeln ('Ambiguous file type. Can''t determine type.');
close (FileCheck);
halt(2);
end;
end;
procedure dos2unix (infile, outfile : string);
var
intext, outtext : text;
ReadBuf1, ReadBuf2 : char;
begin
writeln ('Converting DOS -> UNIX. . . .');
assign (intext, infile);
settextbuf (intext, ibuf, sizeof(ibuf));
reset (intext);
assign (outtext, outfile);
settextbuf (outtext, obuf, sizeof(obuf));
rewrite (outtext);
while not eof(intext) do
begin
read (intext, ReadBuf1); {Get character}
if ReadBuf1 = CR then {If it's CR then. . . }
begin
read (intext, ReadBuf2); {. . . get next . . .}
if ReadBuf2 = LF then {. . . and see if it's LF.}
write (outtext, LF) {If yes, just put LF into new file.}
else
write (outtext, ReadBuf1, ReadBuf2); {Not CR/LF, dump to file.}
end
else
write (outtext, ReadBuf1); {Dump the character to file.}
end;
close (intext);
close (outtext);
end;
procedure unix2dos (infile, outfile : string);
var
intext, outtext : text;
ReadBuf : char;
begin
writeln ('Converting UNIX -> DOS. . . .');
assign (intext, infile);
settextbuf (intext, ibuf, sizeof(ibuf));
reset (intext);
assign (outtext, outfile);
settextbuf (outtext, obuf, sizeof(obuf));
rewrite (outtext);
while not eof(intext) do
begin
read (intext, ReadBuf); {Get a character.}
if ReadBuf = LF then {Is it LF?}
write (outtext, CR+LF) {If yes, put a CR/LF in its place.}
else
write (outtext, ReadBuf); {Otherwise, replace the character.}
end;
close (intext);
close (outtext);
end;
procedure getcommandline;
{get commandline info. . . .}
var
pnum : byte; {paramater counter}
pstr : string[2]; {string snippet}
fname : string; {temporary string}
begin
if (paramcount < 1) or (paramcount > 4) then
help (false); {too few, too many--show help}
infile := ''; {Init names.}
outfile := '';
force := bad;
for pnum := 1 to paramcount do {Do this in two passes.}
begin {#1.) Flags}
pstr := paramstr(pnum); {Get parameter.}
pstr[2] := upcase(pstr[2]);
if pstr[1] in ['-', '/'] then {Flag?}
case pstr[2] of
'H', '?' : help (false); {Is help.}
'D' : force := dos; {Is force DOS.}
'U' : force := unix; {Is force UNIX.}
'O' : overwrite := true; {is overwrite.}
else
help (true); {Bad switch.}
end;
end;
for pnum := 1 to paramcount do {#2.) Filenames}
begin
fname := paramstr(pnum); {Get parameter.}
if not (fname[1] in ['-', '/']) then
begin {If not flag then}
if infile = '' then {Get infile}
infile := fname
else if (infile <> '') and (outfile = '') then
outfile := fname {Get outfile}
else
help (false); {Oops, too many.}
end;
end;
end;
begin
overwrite := false; {Initialize flag}
getcommandline; {Parse parameters}
sysID := checktype (infile); {Check the input file type}
incheck (infile); {verify that infile exists}
if not overwrite then {/o specified?}
outcheck (outfile); {verify that outfile doesn't exist}
if sysID = force then {If it's getting forced, then}
begin {compare types and skip if same.}
write ('Input file is already type ');
case sysID of
dos : write ('DOS');
unix : write ('UNIX');
end;
writeln (', skipped.');
halt(5);
end;
case sysID of
dos : dos2unix (infile, outfile); {DOS -> UNIX}
unix : unix2dos (infile, outfile); {UNIX -> DOS}
bad : begin {Not likely to happen but. . . .}
writeln ('Internal error! Check source code and recompile.');
halt (6);
end;
end;
end.
[Back to TEXTFILE SWAG index] [Back to Main SWAG index] [Original]