fork download
  1. -- BOOK401.ADA Ver. 4.01 2001-SEP-10 Copyright 1988-2001 John J. Herro
  2. --
  3. -- SOFTWARE INNOVATIONS TECHNOLOGY www.adatutor.com
  4. -- 1083 MANDARIN DR NE
  5. -- PALM BAY FL 32905-4706 john@adatutor.com
  6. --
  7. -- (321) 951-0233
  8. --
  9. -- This program creates two printable "book" files from the tutorial text in
  10. -- ADATUTOR.DAT. This is by no means required for the course, but is provided
  11. -- because several users have asked for it. Be prepared to print about 500
  12. -- pages! For the format of the input data file, please see the preliminary
  13. -- comments in ADATU401.ADA.
  14. --
  15. -- This code is written in Ada 83 and will compile on Ada 83 and Ada 95
  16. -- compilers.
  17. --
  18. with Direct_IO, Text_IO; use Text_IO;
  19. procedure Book is
  20. subtype Block_Subtype is String(1 .. 64);
  21. package Random_IO is new Direct_IO(Block_Subtype);
  22. Ix_Size : constant := 35; -- Number of blocks in the index.
  23. Data_File : Random_IO.File_Type; -- The file from which screens are read.
  24. P : File_Type; -- The output file, to be printed.
  25. Block : Block_Subtype; -- Block read from the input file.
  26. Vpos : Integer; -- Number of the current block.
  27. Hpos : Integer; -- Current position within current block.
  28. Highest_SN : Integer; -- Highest screen number in the course.
  29. Middle_SN : Integer; -- Screen number when we change output files.
  30. Indx : String(1 .. 64*Ix_Size); -- Index from the Data File.
  31. Answer : String(1 .. 80); -- User response to questions.
  32. Len : Integer; -- Length of Answer.
  33. File_OK : Boolean := False; -- True when data file opens successfully.
  34. Legal_Note : constant String := " Copyright 1988-2001 John J. Herro ";
  35. -- Legal_Note isn't used by the program, but it causes most
  36. -- compilers to place this string in the executable file.
  37. procedure Open_Input_File is separate;
  38. procedure Open_Output_File(S: in String) is separate;
  39. procedure Print_Instructions is separate;
  40. procedure Print_Title_Page is separate;
  41. procedure Print_Screen(SN : in Integer) is separate;
  42. begin
  43. Open_Input_File;
  44. if File_OK then
  45. Print_Instructions;
  46. Open_Output_File("FIRST");
  47. Print_Title_Page;
  48. Middle_SN := (101 + Highest_SN)/2;
  49. for SN in 101 .. Highest_SN loop
  50. if SN = Middle_SN then
  51. Close(P);
  52. Open_Output_File("SECOND");
  53. end if;
  54. Print_Screen(SN);
  55. end loop;
  56. Put_Line("Both book files are created and ready for printing.");
  57. Random_IO.Close(Data_File);
  58. Close(P);
  59. end if;
  60. end Book;
  61. separate (Book)
  62. procedure Open_Input_File is
  63. Data_File_Name : constant String := "ADATUTOR.DAT";
  64. begin
  65. Random_IO.Open(Data_File, Random_IO.In_File, Data_File_Name);
  66. for I in 1 .. Ix_Size loop -- Read index from start of Data File.
  67. Random_IO.Read(Data_File, Item => Block, From => Random_IO.Count(I));
  68. Indx(64*I - 63 .. 64*I) := Block;
  69. end loop;
  70. Highest_SN := Integer'Value(Indx(6 .. 8));
  71. File_OK := True;
  72. exception
  73. when Random_IO.Name_Error =>
  74. Put("I'm sorry. The file " & Data_File_Name & " seems to be missing.");
  75. when others =>
  76. Put("I'm sorry. The file " & Data_File_Name);
  77. Put_Line(" seems to have the wrong form.");
  78. end Open_Input_File;
  79.  
  80.  
  81.  
  82. separate (Book)
  83. procedure Open_Output_File(S: in String) is
  84. OK : Boolean := False; -- True when file opens successfully.
  85. begin
  86. Put_Line("Please type the name of the output file for the " & S & " half");
  87. Put("of the tutorial: ");
  88. Get_Line(Answer, Len);
  89. while not OK loop
  90. begin
  91. Create(File => P, Mode => Out_File, Name => Answer(1 .. Len));
  92. OK := True;
  93. exception
  94. when others => null;
  95. end;
  96. if not OK then
  97. Put_Line("Unable to create file. Please retype name: ");
  98. Get_Line(Answer, Len);
  99. end if;
  100. end loop;
  101. New_Line(2);
  102. end Open_Output_File;
  103. separate (Book)
  104. procedure Print_Instructions is
  105. begin
  106. Put_Line("This program creates two printable ""book"" files from the");
  107. Put_Line("tutorial text in ADATUTOR.DAT. This is by no means required");
  108. Put_Line("for the course, but is provided because several users have");
  109. Put_Line("asked for it. Be prepared to print about 500 pages!");
  110. New_Line(2);
  111. end Print_Instructions;
  112.  
  113.  
  114.  
  115. separate (Book)
  116. procedure Print_Title_Page is
  117. S : constant String(1 .. 11) := (others => ' ');
  118. begin
  119. New_Page(P);
  120. New_Line(P);
  121. Put_Line(P,S & " AAA d TTTTT t ");
  122. Put_Line(P,S & " A A d aaa T u u ttttt ooo r rrr");
  123. Put_Line(P,S & " AAAAA dddd a a T u u t o o rr ");
  124. Put_Line(P,S & " A A d d a a T u u t o o r ");
  125. Put_Line(P,S & " A A ddd aaaa T uuu t ooo r ");
  126. New_Line(P);
  127. Put_Line(P,S & "This is a copy of the tutorial text from AdaTutor, The");
  128. Put_Line(P,S & "Interactive Ada Tutor, ver. 4.01. BEGIN WITH SCREEN 104.");
  129. New_Line(P);
  130. Put_Line(P,S & " Copyright 1988-2001 John J. Herro");
  131. New_Line(P);
  132. Put_Line(P,S & "You may copy this book, in printed or machine-readable");
  133. Put_Line(P,S & "form, if you observe the Shareware notice in Screen 104.");
  134. Put_Line(P,S & "Please distribute complete copies of the AdaTutor program");
  135. Put_Line(P,S & "along with this book. If you don't have a copy of");
  136. Put_Line(P,S & "AdaTutor, send $35 for a registered copy for full use by");
  137. Put_Line(P,S & "one individual, or visit us on the World Wide Web,");
  138. Put_Line(P,S & "download a trial copy, and register later for $25.");
  139. New_Line(P);
  140. Put_Line(P,S & " SOFTWARE INNOVATIONS TECHNOLOGY");
  141. Put_Line(P,S & " 1083 MANDARIN DR NE");
  142. Put_Line(P,S & " PALM BAY FL 32905-4706");
  143. New_Line(P);
  144. Put_Line(P,S & " (321) 951-0233");
  145. New_Line(P);
  146. Put_Line(P,S & " www.adatutor.com");
  147. New_Page(P);
  148. New_Line(P);
  149. end Print_Title_Page;
  150. separate (Book)
  151. procedure Print_Screen(SN : in Integer) is
  152. Expanding : Boolean := False; -- True when expanding multiple spaces.
  153. Literal : Boolean := False; -- True to print next character as is.
  154. Prompting : Boolean := False; -- True for first character in a prompt.
  155. Bold : Boolean := False; -- True when text is being emphasized.
  156. Outp1, Outp2 : String(1 ..120) := (others => ' '); -- Lines of output text.
  157. Place : Integer := 1; -- Current position within Outp1 and Outp2.
  158. Limit : Integer; -- Position of last non-space char. in Outp2.
  159. Line_Num : Integer := 1; -- Current line being displayed.
  160. Space : constant String(1 .. 69) := (others => ' ');
  161. procedure Show(C : in Character) is separate;
  162. procedure Screen_Char is separate;
  163. procedure End_Of_Screen is separate;
  164. begin
  165. if SN = 103 then
  166. Put(P, Space(1 .. 27) & "*** X TAKES YOU HERE. ***");
  167. Put_Line(P, Space(1 .. 17) & "Screen 103");
  168. else
  169. Put_Line(P, Space & "Screen" & Integer'Image(SN));
  170. end if;
  171. New_Line(P, 2);
  172. Vpos := 95*(Character'Pos(Indx(SN*4 - 394)) - 32) + -- Point to start
  173. Character'Pos(Indx(SN*4 - 393)) - 32; -- of current
  174. Hpos := Character'Pos(Indx(SN*4 - 392)) - 32; -- screen.
  175. Random_IO.Read(Data_File, Item => Block, From => Random_IO.Count(Vpos));
  176. while Block(Hpos) /= '[' or Expanding or Literal loop -- [ starts ctrl info.
  177. Screen_Char;
  178. end loop;
  179. End_Of_Screen;
  180. end Print_Screen;
  181. separate (Book.Print_Screen)
  182. procedure Show(C : in Character) is
  183. begin
  184. Outp1(Place) := C;
  185. if Bold then
  186. Outp2(Place) := '-';
  187. end if;
  188. Place := Place + 1;
  189. end Show;
  190.  
  191.  
  192.  
  193. separate (Book.Print_Screen)
  194. procedure Screen_Char is
  195. procedure Process_Char is separate;
  196. begin
  197. if Expanding then
  198. if Block(Hpos) = '!' then
  199. Literal := True;
  200. else
  201. for I in Integer range 1 .. Character'Pos(Block(Hpos)) - 32 loop
  202. Show(' ');
  203. end loop;
  204. end if;
  205. Expanding := False;
  206. elsif Literal then
  207. Show(Block(Hpos));
  208. Literal := False;
  209. elsif Prompting then
  210. Prompting := False;
  211. if Block(Hpos) = 'b' then
  212. Put(P, "Please type a space to go on, or B to go back.");
  213. elsif Block(Hpos) = 'q' then
  214. Put(P, "Please type a space to go on, or B to go back ");
  215. Put(P, "to the question.");
  216. else
  217. Process_Char;
  218. end if;
  219. else
  220. Process_Char;
  221. end if;
  222. Hpos := Hpos + 1;
  223. if Hpos > Block'Length then
  224. Vpos := Vpos + 1;
  225. Hpos := 1;
  226. Random_IO.Read(Data_File, Block, From => Random_IO.Count(Vpos));
  227. end if;
  228. end Screen_Char;
  229. separate (Book.Print_Screen.Screen_Char)
  230. procedure Process_Char is
  231. begin
  232. case Block(Hpos) is
  233. when '{' => Put_Line(P, Outp1(1 .. Place - 1));
  234. Limit := Outp2'Last;
  235. while Limit > 0 and then Outp2(Limit) = ' ' loop
  236. Limit := Limit - 1;
  237. end loop;
  238. Put_Line(P, Outp2(1 .. Limit));
  239. Outp2 := (others => ' ');
  240. Line_Num := Line_Num + 1;
  241. Outp1 := (others => ' ');
  242. Place := 1;
  243. when '`' => Expanding := True; -- ` = several spaces.
  244. when '^' => Bold := not Bold; -- ^ = toggle bright.
  245. when '}' => for I in Line_Num .. 23 loop -- } = go to line 24.
  246. New_Line(P, 2);
  247. end loop;
  248. Prompting := True;
  249. when '~' => null; -- ~ = toggle rev. vid.
  250. when '$' => if SN = 103 then -- $ = screen #.
  251. Show(' '); Show('_'); Show('_'); Show('_');
  252. else
  253. Show('$');
  254. end if;
  255. when '#' => if SN = 103 then -- # = % completed.
  256. Show(' '); Show('_'); Show('_');
  257. else
  258. Show('#');
  259. end if;
  260. when others => Show(Block(Hpos));
  261. end case;
  262. end Process_Char;
  263. separate (Book.Print_Screen)
  264. procedure End_Of_Screen is
  265. Ctrl_Info : Block_Subtype; -- Control info. for the current screen.
  266. I : Integer; -- Used to index through Ctrl_Info.
  267. begin
  268. Put_Line(P, Outp1(1 .. Place - 1));
  269. Limit := Outp2'Last;
  270. while Limit > 0 and then Outp2(Limit) = ' ' loop
  271. Limit := Limit - 1;
  272. end loop;
  273. Put_Line(P, Outp2(1 .. Limit));
  274. Place := 1;
  275. while Block(Hpos) /= ']' loop -- Read control information from Data File.
  276. Hpos := Hpos + 1;
  277. if Hpos > Block'Length then
  278. Vpos := Vpos + 1;
  279. Hpos := 1;
  280. Random_IO.Read(Data_File, Block, From => Random_IO.Count(Vpos));
  281. end if;
  282. Ctrl_Info(Place) := Block(Hpos);
  283. Place := Place + 1;
  284. end loop;
  285. if Ctrl_Info(1 .. Place - 1) = "]" then
  286. Put_Line(P, "(Program ends after this screen.)");
  287. elsif Ctrl_Info(1 .. Place - 1) = "#]" then
  288. Put_Line(P, "(User types the next screen number.)");
  289. else
  290. I := 1;
  291. while I + 4 < Place loop
  292. Put(P, " '" & Ctrl_Info(I) & "' " & Ctrl_Info(I+1..I+3));
  293. I := I + 4;
  294. if I = 33 then
  295. New_Line(P);
  296. end if;
  297. end loop;
  298. New_Line(P);
  299. end if;
  300. New_Page(P);
  301. New_Line(P);
  302. end End_Of_Screen;
  303.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
21
compilation info
gnatgcc -c -pipe -O2 prog.adb
prog.adb:63:01: end of file expected, file can have only one compilation unit
gnatmake: "prog.adb" compilation error
stdout
Standard output is empty