fixtab.pp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. program FixTab;
  2. uses Dos;
  3. const
  4. {Files}
  5. InputExt='';
  6. OutputExt='*';
  7. var
  8. {General}
  9. InFile,
  10. OutFile : string[80];
  11. ParaFile : word;
  12. {Specific}
  13. const
  14. TabSize : longint=8;
  15. DosEol : boolean=false;
  16. Verbose : boolean=false;
  17. {****************************************************************************
  18. Routines
  19. ****************************************************************************}
  20. const
  21. {$IFDEF LINUX}
  22. PathCh='/';
  23. {$ELSE}
  24. PathCh='\';
  25. {$ENDIF}
  26. Function SplitPath(Const HStr:String):String;
  27. var
  28. i : byte;
  29. begin
  30. i:=Length(Hstr);
  31. while (i>0) and (Hstr[i]<>PathCh) do
  32. dec(i);
  33. SplitPath:=Copy(Hstr,1,i);
  34. end;
  35. Function SplitFileName(Const HStr:String):String;
  36. var
  37. i : byte;
  38. begin
  39. i:=Length(Hstr);
  40. while (i>0) and (Hstr[i]<>PathCh) do
  41. dec(i);
  42. SplitFileName:=Copy(Hstr,i+1,255);
  43. end;
  44. Function SplitName(Const HStr:String):String;
  45. var
  46. i,j : byte;
  47. begin
  48. i:=Length(Hstr);
  49. j:=i;
  50. while (i>0) and (Hstr[i]<>PathCh) do
  51. dec(i);
  52. while (j>0) and (Hstr[j]<>'.') do
  53. dec(j);
  54. if j<=i then
  55. j:=255;
  56. SplitName:=Copy(Hstr,i+1,j-(i+1));
  57. end;
  58. Function SplitExtension(Const HStr:String):String;
  59. var
  60. j,i : byte;
  61. begin
  62. i:=Length(Hstr);
  63. j:=i;
  64. while (i>0) and (Hstr[i]<>PathCh) do
  65. dec(i);
  66. while (j>0) and (Hstr[j]<>'.') do
  67. dec(j);
  68. if j<=i then
  69. j:=254;
  70. SplitExtension:=Copy(Hstr,j+1,255);
  71. end;
  72. Function ChangeFileExt(Const HStr,ext:String):String;
  73. begin
  74. if (Ext<>'') and (SplitExtension(HStr)='') then
  75. ChangeFileExt:=Hstr+'.'+Ext
  76. else
  77. ChangeFileExt:=Hstr;
  78. end;
  79. Function ForceExtension(Const HStr,ext:String):String;
  80. var
  81. j : byte;
  82. begin
  83. j:=length(Hstr);
  84. while (j>0) and (Hstr[j]<>'.') do
  85. dec(j);
  86. if j=0 then
  87. j:=255;
  88. ForceExtension:=Copy(Hstr,1,j-1)+'.'+Ext;
  89. end;
  90. function UCase(Const Hstr:string):string;
  91. var
  92. i : byte;
  93. begin
  94. for i:=1to Length(Hstr) do
  95. UCase[i]:=Upcase(Hstr[i]);
  96. UCase[0]:=chr(Length(Hstr));
  97. end;
  98. Function ESpace(HStr:String;len:byte):String;
  99. begin
  100. while length(Hstr)<Len do
  101. begin
  102. inc(byte(Hstr[0]));
  103. Hstr[Length(Hstr)]:=' ';
  104. end;
  105. ESpace:=Hstr;
  106. end;
  107. {****************************************************************************
  108. Main Stuff
  109. ****************************************************************************}
  110. var
  111. Done : array[0..1023] of string[32];
  112. Total : word;
  113. Function FileDone(const fn:string):boolean;
  114. var
  115. i : word;
  116. begin
  117. i:=0;
  118. while (i<Total) and (Done[i]<>fn) do
  119. inc(i);
  120. if Done[i]=fn then
  121. FileDone:=true
  122. else
  123. begin
  124. Done[Total]:=fn;
  125. inc(Total);
  126. FileDone:=false;
  127. end;
  128. end;
  129. procedure Convert(fn,nfn:string);
  130. type
  131. inbuftype=array[0..31999] of char;
  132. outbuftype=array[0..63999] of char;
  133. var
  134. f,g : file;
  135. inbuf : ^inbuftype;
  136. outbuf : ^outbuftype;
  137. Curr,
  138. TabCol,
  139. col,
  140. i,last,
  141. innum,
  142. outnum : longint;
  143. procedure WriteBuf;
  144. begin
  145. if i>last then
  146. begin
  147. move(InBuf^[last],OutBuf^[OutNum],i-last);
  148. inc(OutNum,(i-last));
  149. end;
  150. Last:=i+1;
  151. end;
  152. begin
  153. {Create New FileName}
  154. if SplitExtension(nfn)='*' then
  155. nfn:=ChangeFileExt(SplitPath(nfn)+SplitName(nfn),SplitExtension(fn));
  156. if SplitName(nfn)='*' then
  157. begin
  158. if SplitPath(nfn)='' then
  159. nfn:=ChangeFileExt(SplitPath(fn)+SplitName(fn),SplitExtension(nfn))
  160. else
  161. nfn:=ChangeFileExt(SplitPath(nfn)+SplitName(fn),SplitExtension(nfn));
  162. end;
  163. {Done?}
  164. if FileDone(nfn) then
  165. exit;
  166. {Open Files}
  167. Write('Converting '+ESpace(fn,30)+' ');
  168. if fn=nfn then
  169. assign(g,ForceExtension(fn,'$T$'))
  170. else
  171. begin
  172. Write('-> '+ESpace(nfn,30)+' ');
  173. assign(g,nfn);
  174. end;
  175. new(inbuf);
  176. new(outbuf);
  177. assign(f,fn);
  178. {$I-}
  179. reset(f,1);
  180. {$I+}
  181. if ioresult<>0 then
  182. exit;
  183. {$I-}
  184. rewrite(g,1);
  185. {$I+}
  186. if ioresult<>0 then
  187. begin
  188. close(f);
  189. exit;
  190. end;
  191. Curr:=0;
  192. col:=1;
  193. last:=0;
  194. repeat
  195. blockread(f,InBuf^,sizeof(InBufType),innum);
  196. outnum:=0;
  197. if innum>0 then
  198. begin
  199. i:=0;
  200. while (i<innum) do
  201. begin
  202. case InBuf^[i] of
  203. #9 : begin
  204. WriteBuf;
  205. OutBuf^[OutNum]:=' ';
  206. inc(OutNum);
  207. inc(Col);
  208. TabCol:=(((Col-1) div TabSize)+1)*TabSize;
  209. while (Col<TabCol) do
  210. begin
  211. OutBuf^[OutNum]:=' ';
  212. inc(OutNum);
  213. inc(Col);
  214. end;
  215. end;
  216. #13 : begin
  217. WriteBuf;
  218. while (outnum>0) and (outbuf^[outnum-1] in [' ',#9]) do
  219. dec(outnum);
  220. end;
  221. #10 : begin
  222. WriteBuf;
  223. while (outnum>0) and (outbuf^[outnum-1] in [' ',#9]) do
  224. dec(outnum);
  225. if DosEol then
  226. begin
  227. OutBuf^[OutNum]:=#13;
  228. inc(OutNum);
  229. end;
  230. OutBuf^[OutNum]:=#10;
  231. inc(OutNum);
  232. col:=0;
  233. inc(Curr);
  234. if (curr and 31)=0 then
  235. Write(Curr:5,#8#8#8#8#8);
  236. end;
  237. else
  238. inc(col);
  239. end;
  240. inc(i);
  241. end;
  242. WriteBuf;
  243. last:=0;
  244. end;
  245. blockwrite(g,OutBuf^,outnum);
  246. until innum=0;
  247. WriteLn(Curr,' Lines');
  248. close(g);
  249. close(f);
  250. if fn=nfn then
  251. begin
  252. erase(f);
  253. rename(g,fn);
  254. end;
  255. dispose(outbuf);
  256. dispose(inbuf);
  257. end;
  258. {****************************************************************************
  259. General Stuff
  260. ****************************************************************************}
  261. procedure getpara;
  262. var
  263. ch : char;
  264. para : string[128];
  265. i,j : word;
  266. procedure helpscreen;
  267. begin
  268. writeln('Usage : '+SplitName(ParamStr(0))+' [Options] <InFile(s)>'#10);
  269. writeln('<Options> can be : -O<OutFile> Specify OutFile Mask');
  270. WriteLn(' -D Use MsDos #13#10 Eols');
  271. writeln(' -T<size> Set Size of Tabs');
  272. writeln(' -V be more verbose');
  273. writeln(' -? or -H This HelpScreen');
  274. halt(1);
  275. end;
  276. begin
  277. for i:=1to paramcount do
  278. begin
  279. para:=ucase(paramstr(i));
  280. if (para[1]='-') then
  281. begin
  282. ch:=para[2];
  283. delete(para,1,2);
  284. case ch of
  285. 'O' : OutFile:=ChangeFileExt(Para,OutputExt);
  286. 'D' : DosEol:=true;
  287. 'T' : Val(Para,TabSize,j);
  288. 'V' : verbose:=true;
  289. '?','H' : helpscreen;
  290. end;
  291. end
  292. else
  293. begin
  294. if ParaFile=0 then
  295. ParaFile:=i;
  296. end;
  297. end;
  298. if (ParaFile=0) then
  299. HelpScreen;
  300. if OutFile='' then
  301. OutFile:=ForceExtension('*',OutPutExt);
  302. end;
  303. var
  304. Dir : SearchRec;
  305. i : word;
  306. begin
  307. GetPara;
  308. {Main}
  309. if Verbose then
  310. begin
  311. Writeln('fixtab v1.01 (C) 1999-2002 Peter Vreman');
  312. Writeln('TabSize ',TabSize);
  313. if DosEol then
  314. WriteLn('Using MsDos Eols');
  315. end;
  316. for i:=ParaFile to ParamCount do
  317. begin
  318. InFile:=ChangeFileExt(ParamStr(i),InputExt);
  319. FindFirst(InFile,$20,Dir);
  320. while (DosError=0) do
  321. begin
  322. Convert(SplitPath(InFile)+Dir.Name,OutFile);
  323. FindNext(Dir);
  324. end;
  325. end;
  326. end.