home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c081_7 / 7.ddi / TDEXMPL.ZIP / TPDEMOB.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1991-02-13  |  5.5 KB  |  237 lines

  1. {$N+,E+}
  2.  
  3. (* File: TPDEMOB.PAS
  4.  
  5.    Broken Turbo Pascal Demonstration program to show off Turbo Debugger
  6.    Copyright (c) 1988, 1989 - Borland Intl.
  7.  
  8.    Reads words from standard input, analyzes letter and word frequency.
  9.    Uses linked list to store commandline parameters on heap.
  10.  
  11.    Uses the following data types:
  12.  
  13.      Boolean,
  14.      Char, Byte,
  15.      Integer, Word,
  16.      LongInt,
  17.      Extended (8087 type, links in emulator)
  18.      String,
  19.      Array,
  20.      Record,
  21.      Set,
  22.      Pointer
  23.  
  24.   Comments that look like this:
  25.  
  26.     { ** Bug: <description> }
  27.  
  28.   are inserted above lines that contain bugs.
  29.  
  30. *)
  31. program TPDemo;
  32.  
  33. const
  34.   BufSize    = 128;    { length of line buffer }
  35.   MaxWordLen =  10;    { maximum word length allowed }
  36.  
  37. type
  38.   BufferStr = String[BufSize];
  39.  
  40.   LInfoRec = record
  41.     Count : Word;               { number of occurrences of this letter }
  42.     FirstLetter : Word;         { number of times as first letter of a }
  43.   end;
  44.  
  45.  
  46. var
  47.   NumLines, NumWords : Word;                     { counters }
  48.   NumLetters : LongInt;
  49.   WordLenTable : array [1..MaxWordLen] of Word;  { info for each word }
  50.   LetterTable : array['A'..'Z'] of LInfoRec;     { info for each letter }
  51.   Buffer : BufferStr;
  52.  
  53. procedure ShowResults;
  54.  
  55. procedure ShowLetterInfo(FromLet, ToLet : Char);
  56. { Dump letter information }
  57. var
  58.   ch : Char;
  59. begin
  60.   Writeln;
  61.   Write('Letter:     ');
  62.   { ** Bug: Extra semicolon }
  63.   for ch := FromLet to ToLet do;                { column titles }
  64.     Write(ch:5);
  65.   Writeln;
  66.  
  67.   Write('Frequency:  ');
  68.   for ch := FromLet to ToLet do                 { letter count }
  69.     Write(LetterTable[ch].Count:5);
  70.   Writeln;
  71.   Write('Word starts:');
  72.   for ch := FromLet to ToLet do                 { first letter count }
  73.     Write(LetterTable[ch].FirstLetter:5);
  74.   Writeln;
  75. end; { ShowLetterInfo }
  76.  
  77. var
  78.   i : Integer;
  79.   AvgWords : Extended;
  80.  
  81. begin { ShowResults }
  82.   { ** Bug: should test to avoid divide by zero; should be words per line }
  83.   AvgWords := NumLines / NumWords;
  84.   Writeln;
  85.   Writeln(NumLetters, ' char(s) in ',
  86.           NumWords, ' word(s) in ',
  87.           NumLines, ' line(s)');
  88.   Writeln('Average of ', AvgWords:0:2, ' words per line');
  89.   Writeln;
  90.  
  91.   { Dump word count }
  92.   Write('Word length:');
  93.   for i := 1 to MaxWordLen do
  94.     Write(i:4);
  95.   Writeln;
  96.  
  97.   Write('Frequency:  ');
  98.   for i := 1 to MaxWordLen do
  99.     Write(WordLenTable[i]:4);
  100.   Writeln;
  101.  
  102.   { Dump letter counts }
  103.   ShowLetterInfo('A', 'M');
  104.   ShowLetterInfo('N', 'Z');
  105. end; { ShowResults }
  106.  
  107. procedure Init;
  108. begin
  109.   NumLines := 0; NumWords := 0; NumLetters := 0;
  110.   FillChar(LetterTable, SizeOf(LetterTable), 0);
  111.   FillChar(WordLenTable, SizeOf(WordLenTable), 0);
  112.   Writeln('Enter a string to process, an empty string quits.');
  113. end; { Init }
  114.  
  115. procedure ProcessLine(S : BufferStr);
  116.  
  117. function IsLetter(ch : Char) : Boolean;
  118. begin
  119.   { ** Bug: Should shift character to uppercase before testing }
  120.   IsLetter := ch in ['A'..'Z'];
  121. end; { IsLetter }
  122.  
  123. var
  124.   i : Integer;
  125.   WordLen : Word;
  126.  
  127. begin { ProcessLine }
  128.   Inc(NumLines);
  129.   i := 1;
  130.   while i <= Length(S) do
  131.   begin
  132.     { Skip non-letters }
  133.     while (i <= Length(S)) and not IsLetter(S[i]) do
  134.       Inc(i);
  135.  
  136.     { Find end of word, bump letter & word counters }
  137.     WordLen := 0;
  138.     while (i <= Length(S)) and IsLetter(S[i]) do
  139.     begin
  140.       Inc(NumLetters);
  141.       Inc(LetterTable[UpCase(S[i])].Count);
  142.       if WordLen = 0 then                    { bump counter }
  143.         Inc(LetterTable[UpCase(S[i])].FirstLetter);
  144.       Inc(i);
  145.       Inc(WordLen);
  146.     end;
  147.  
  148.     { Bump word count info }
  149.     if WordLen > 0 then
  150.     begin
  151.       Inc(NumWords);
  152.       if WordLen <= MaxWordLen then
  153.         Inc(WordLenTable[WordLen]);
  154.     end;
  155.   end; { while }
  156. end; { ProcessLine }
  157.  
  158. function GetLine : BufferStr;
  159. var
  160.   S : BufferStr;
  161. begin
  162.   Write('String: ');
  163.   Readln(S);
  164.   GetLine := S;
  165. end;
  166.  
  167. procedure ParmsOnHeap;
  168. { Builds a linked list of commandline parameters on the heap.
  169.   Note that the zero'th parameter, ParamStr(0), returns the
  170.   Exec name of the program on Dos 3.xx only.
  171. }
  172. type
  173.   ParmRecPtr = ^ParmRec;
  174.   ParmRec = record
  175.     Parm : ^String;
  176.     Next : ParmRecPtr;
  177.   end;
  178. var
  179.   Head, Tail, Temp : ParmRecPtr;
  180.   i : Integer;
  181.   s : String;
  182. begin
  183.   Head := nil;
  184.   for i := 0 to ParamCount do
  185.   begin
  186.     { Get next commandline parameter }
  187.     s := ParamStr(i);
  188.     if MaxAvail < SizeOf(ParmRec) + Length(s) + 1 then  { room on heap? }
  189.     begin
  190.       Writeln('Heap full, procedure aborting...');
  191.       Exit;
  192.     end;
  193.  
  194.     { Add to linked list }
  195.     New(Temp);                         { another Parm record }
  196.     with Temp^ do
  197.     begin
  198.       { ** Bug: Should allocate enough for length byte }
  199.       GetMem(Parm, Length(s));         { string + length byte }
  200.       Parm^ := s;
  201.       Next := nil;
  202.     end;
  203.     if Head = nil then                 { initialize list pointer }
  204.       Head := Temp
  205.     else
  206.       Tail^.Next := Temp;              { add to end }
  207.     Tail := Temp;                      { update tail pointer }
  208.   end; { for }
  209.  
  210.   { Dump list }
  211.   Writeln;
  212.   with Head^ do
  213.     if Parm^ <> '' then
  214.       Writeln('Program name: ', Parm^);
  215.   Write('Command line parameters: ');
  216.   Tail := Head^.Next;
  217.   while Tail <> nil do
  218.     with Tail^ do
  219.     begin
  220.       Write(Parm^, ' ');
  221.       Tail := Next;
  222.     end;
  223.   Writeln;
  224. end; { ParmsOnHeap }
  225.  
  226. begin { program }
  227.   Init;
  228.   Buffer := GetLine;
  229.   while Buffer <> '' do
  230.   begin
  231.     ProcessLine(Buffer);
  232.     Buffer := GetLine;
  233.   end;
  234.   ShowResults;
  235.   ParmsOnHeap;
  236. end.
  237.