ncurses2-trace_set.adb 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. ------------------------------------------------------------------------------
  2. -- --
  3. -- GNAT ncurses Binding Samples --
  4. -- --
  5. -- ncurses2.trace_set --
  6. -- --
  7. -- B O D Y --
  8. -- --
  9. ------------------------------------------------------------------------------
  10. -- Copyright (c) 2000-2006,2008 Free Software Foundation, Inc. --
  11. -- --
  12. -- Permission is hereby granted, free of charge, to any person obtaining a --
  13. -- copy of this software and associated documentation files (the --
  14. -- "Software"), to deal in the Software without restriction, including --
  15. -- without limitation the rights to use, copy, modify, merge, publish, --
  16. -- distribute, distribute with modifications, sublicense, and/or sell --
  17. -- copies of the Software, and to permit persons to whom the Software is --
  18. -- furnished to do so, subject to the following conditions: --
  19. -- --
  20. -- The above copyright notice and this permission notice shall be included --
  21. -- in all copies or substantial portions of the Software. --
  22. -- --
  23. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS --
  24. -- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF --
  25. -- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. --
  26. -- IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, --
  27. -- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR --
  28. -- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR --
  29. -- THE USE OR OTHER DEALINGS IN THE SOFTWARE. --
  30. -- --
  31. -- Except as contained in this notice, the name(s) of the above copyright --
  32. -- holders shall not be used in advertising or otherwise to promote the --
  33. -- sale, use or other dealings in this Software without prior written --
  34. -- authorization. --
  35. ------------------------------------------------------------------------------
  36. -- Author: Eugene V. Melaragno <aldomel@ix.netcom.com> 2000
  37. -- Version Control
  38. -- $Revision: 1.3 $
  39. -- $Date: 2008/07/26 18:46:18 $
  40. -- Binding Version 01.00
  41. ------------------------------------------------------------------------------
  42. with ncurses2.util; use ncurses2.util;
  43. with Terminal_Interface.Curses; use Terminal_Interface.Curses;
  44. with Terminal_Interface.Curses.Trace; use Terminal_Interface.Curses.Trace;
  45. with Terminal_Interface.Curses.Menus; use Terminal_Interface.Curses.Menus;
  46. with Ada.Strings.Bounded;
  47. -- interactively set the trace level
  48. procedure ncurses2.trace_set is
  49. function menu_virtualize (c : Key_Code) return Menu_Request_Code;
  50. function subset (super, sub : Trace_Attribute_Set) return Boolean;
  51. function trace_or (a, b : Trace_Attribute_Set) return Trace_Attribute_Set;
  52. function trace_num (tlevel : Trace_Attribute_Set) return String;
  53. function tracetrace (tlevel : Trace_Attribute_Set) return String;
  54. function run_trace_menu (m : Menu; count : Integer) return Boolean;
  55. function menu_virtualize (c : Key_Code) return Menu_Request_Code is
  56. begin
  57. case c is
  58. when Character'Pos (newl) | Key_Exit =>
  59. return Menu_Request_Code'Last + 1; -- MAX_COMMAND? TODO
  60. when Character'Pos ('u') =>
  61. return M_ScrollUp_Line;
  62. when Character'Pos ('d') =>
  63. return M_ScrollDown_Line;
  64. when Character'Pos ('b') | Key_Next_Page =>
  65. return M_ScrollUp_Page;
  66. when Character'Pos ('f') | Key_Previous_Page =>
  67. return M_ScrollDown_Page;
  68. when Character'Pos ('n') | Key_Cursor_Down =>
  69. return M_Next_Item;
  70. when Character'Pos ('p') | Key_Cursor_Up =>
  71. return M_Previous_Item;
  72. when Character'Pos (' ') =>
  73. return M_Toggle_Item;
  74. when Key_Mouse =>
  75. return c;
  76. when others =>
  77. Beep;
  78. return c;
  79. end case;
  80. end menu_virtualize;
  81. type string_a is access String;
  82. type tbl_entry is record
  83. name : string_a;
  84. mask : Trace_Attribute_Set;
  85. end record;
  86. t_tbl : constant array (Positive range <>) of tbl_entry :=
  87. (
  88. (new String'("Disable"),
  89. Trace_Disable),
  90. (new String'("Times"),
  91. Trace_Attribute_Set'(Times => True, others => False)),
  92. (new String'("Tputs"),
  93. Trace_Attribute_Set'(Tputs => True, others => False)),
  94. (new String'("Update"),
  95. Trace_Attribute_Set'(Update => True, others => False)),
  96. (new String'("Cursor_Move"),
  97. Trace_Attribute_Set'(Cursor_Move => True, others => False)),
  98. (new String'("Character_Output"),
  99. Trace_Attribute_Set'(Character_Output => True, others => False)),
  100. (new String'("Ordinary"),
  101. Trace_Ordinary),
  102. (new String'("Calls"),
  103. Trace_Attribute_Set'(Calls => True, others => False)),
  104. (new String'("Virtual_Puts"),
  105. Trace_Attribute_Set'(Virtual_Puts => True, others => False)),
  106. (new String'("Input_Events"),
  107. Trace_Attribute_Set'(Input_Events => True, others => False)),
  108. (new String'("TTY_State"),
  109. Trace_Attribute_Set'(TTY_State => True, others => False)),
  110. (new String'("Internal_Calls"),
  111. Trace_Attribute_Set'(Internal_Calls => True, others => False)),
  112. (new String'("Character_Calls"),
  113. Trace_Attribute_Set'(Character_Calls => True, others => False)),
  114. (new String'("Termcap_TermInfo"),
  115. Trace_Attribute_Set'(Termcap_TermInfo => True, others => False)),
  116. (new String'("Maximium"),
  117. Trace_Maximum)
  118. );
  119. package BS is new Ada.Strings.Bounded.Generic_Bounded_Length (300);
  120. function subset (super, sub : Trace_Attribute_Set) return Boolean is
  121. begin
  122. if
  123. (super.Times or not sub.Times) and
  124. (super.Tputs or not sub.Tputs) and
  125. (super.Update or not sub.Update) and
  126. (super.Cursor_Move or not sub.Cursor_Move) and
  127. (super.Character_Output or not sub.Character_Output) and
  128. (super.Calls or not sub.Calls) and
  129. (super.Virtual_Puts or not sub.Virtual_Puts) and
  130. (super.Input_Events or not sub.Input_Events) and
  131. (super.TTY_State or not sub.TTY_State) and
  132. (super.Internal_Calls or not sub.Internal_Calls) and
  133. (super.Character_Calls or not sub.Character_Calls) and
  134. (super.Termcap_TermInfo or not sub.Termcap_TermInfo) and
  135. True then
  136. return True;
  137. else
  138. return False;
  139. end if;
  140. end subset;
  141. function trace_or (a, b : Trace_Attribute_Set) return Trace_Attribute_Set is
  142. retval : Trace_Attribute_Set := Trace_Disable;
  143. begin
  144. retval.Times := (a.Times or b.Times);
  145. retval.Tputs := (a.Tputs or b.Tputs);
  146. retval.Update := (a.Update or b.Update);
  147. retval.Cursor_Move := (a.Cursor_Move or b.Cursor_Move);
  148. retval.Character_Output := (a.Character_Output or b.Character_Output);
  149. retval.Calls := (a.Calls or b.Calls);
  150. retval.Virtual_Puts := (a.Virtual_Puts or b.Virtual_Puts);
  151. retval.Input_Events := (a.Input_Events or b.Input_Events);
  152. retval.TTY_State := (a.TTY_State or b.TTY_State);
  153. retval.Internal_Calls := (a.Internal_Calls or b.Internal_Calls);
  154. retval.Character_Calls := (a.Character_Calls or b.Character_Calls);
  155. retval.Termcap_TermInfo := (a.Termcap_TermInfo or b.Termcap_TermInfo);
  156. return retval;
  157. end trace_or;
  158. -- Print the hexadecimal value of the mask so
  159. -- users can set it from the command line.
  160. function trace_num (tlevel : Trace_Attribute_Set) return String is
  161. result : Integer := 0;
  162. m : Integer := 1;
  163. begin
  164. if tlevel.Times then
  165. result := result + m;
  166. end if;
  167. m := m * 2;
  168. if tlevel.Tputs then
  169. result := result + m;
  170. end if;
  171. m := m * 2;
  172. if tlevel.Update then
  173. result := result + m;
  174. end if;
  175. m := m * 2;
  176. if tlevel.Cursor_Move then
  177. result := result + m;
  178. end if;
  179. m := m * 2;
  180. if tlevel.Character_Output then
  181. result := result + m;
  182. end if;
  183. m := m * 2;
  184. if tlevel.Calls then
  185. result := result + m;
  186. end if;
  187. m := m * 2;
  188. if tlevel.Virtual_Puts then
  189. result := result + m;
  190. end if;
  191. m := m * 2;
  192. if tlevel.Input_Events then
  193. result := result + m;
  194. end if;
  195. m := m * 2;
  196. if tlevel.TTY_State then
  197. result := result + m;
  198. end if;
  199. m := m * 2;
  200. if tlevel.Internal_Calls then
  201. result := result + m;
  202. end if;
  203. m := m * 2;
  204. if tlevel.Character_Calls then
  205. result := result + m;
  206. end if;
  207. m := m * 2;
  208. if tlevel.Termcap_TermInfo then
  209. result := result + m;
  210. end if;
  211. m := m * 2;
  212. return result'Img;
  213. end trace_num;
  214. function tracetrace (tlevel : Trace_Attribute_Set) return String is
  215. use BS;
  216. buf : Bounded_String := To_Bounded_String ("");
  217. begin
  218. -- The C version prints the hexadecimal value of the mask, we
  219. -- won't do that here because this is Ada.
  220. if tlevel = Trace_Disable then
  221. Append (buf, "Trace_Disable");
  222. else
  223. if subset (tlevel,
  224. Trace_Attribute_Set'(Times => True, others => False)) then
  225. Append (buf, "Times");
  226. Append (buf, ", ");
  227. end if;
  228. if subset (tlevel,
  229. Trace_Attribute_Set'(Tputs => True, others => False)) then
  230. Append (buf, "Tputs");
  231. Append (buf, ", ");
  232. end if;
  233. if subset (tlevel,
  234. Trace_Attribute_Set'(Update => True, others => False)) then
  235. Append (buf, "Update");
  236. Append (buf, ", ");
  237. end if;
  238. if subset (tlevel,
  239. Trace_Attribute_Set'(Cursor_Move => True,
  240. others => False)) then
  241. Append (buf, "Cursor_Move");
  242. Append (buf, ", ");
  243. end if;
  244. if subset (tlevel,
  245. Trace_Attribute_Set'(Character_Output => True,
  246. others => False)) then
  247. Append (buf, "Character_Output");
  248. Append (buf, ", ");
  249. end if;
  250. if subset (tlevel,
  251. Trace_Ordinary) then
  252. Append (buf, "Ordinary");
  253. Append (buf, ", ");
  254. end if;
  255. if subset (tlevel,
  256. Trace_Attribute_Set'(Calls => True, others => False)) then
  257. Append (buf, "Calls");
  258. Append (buf, ", ");
  259. end if;
  260. if subset (tlevel,
  261. Trace_Attribute_Set'(Virtual_Puts => True,
  262. others => False)) then
  263. Append (buf, "Virtual_Puts");
  264. Append (buf, ", ");
  265. end if;
  266. if subset (tlevel,
  267. Trace_Attribute_Set'(Input_Events => True,
  268. others => False)) then
  269. Append (buf, "Input_Events");
  270. Append (buf, ", ");
  271. end if;
  272. if subset (tlevel,
  273. Trace_Attribute_Set'(TTY_State => True,
  274. others => False)) then
  275. Append (buf, "TTY_State");
  276. Append (buf, ", ");
  277. end if;
  278. if subset (tlevel,
  279. Trace_Attribute_Set'(Internal_Calls => True,
  280. others => False)) then
  281. Append (buf, "Internal_Calls");
  282. Append (buf, ", ");
  283. end if;
  284. if subset (tlevel,
  285. Trace_Attribute_Set'(Character_Calls => True,
  286. others => False)) then
  287. Append (buf, "Character_Calls");
  288. Append (buf, ", ");
  289. end if;
  290. if subset (tlevel,
  291. Trace_Attribute_Set'(Termcap_TermInfo => True,
  292. others => False)) then
  293. Append (buf, "Termcap_TermInfo");
  294. Append (buf, ", ");
  295. end if;
  296. if subset (tlevel,
  297. Trace_Maximum) then
  298. Append (buf, "Maximium");
  299. Append (buf, ", ");
  300. end if;
  301. end if;
  302. if To_String (buf) (Length (buf) - 1) = ',' then
  303. Delete (buf, Length (buf) - 1, Length (buf));
  304. end if;
  305. return To_String (buf);
  306. end tracetrace;
  307. function run_trace_menu (m : Menu; count : Integer) return Boolean is
  308. i, p : Item;
  309. changed : Boolean;
  310. c, v : Key_Code;
  311. begin
  312. loop
  313. changed := (count /= 0);
  314. c := Getchar (Get_Window (m));
  315. v := menu_virtualize (c);
  316. case Driver (m, v) is
  317. when Unknown_Request =>
  318. return False;
  319. when others =>
  320. i := Current (m);
  321. if i = Menus.Items (m, 1) then -- the first item
  322. for n in t_tbl'First + 1 .. t_tbl'Last loop
  323. if Value (i) then
  324. Set_Value (i, False);
  325. changed := True;
  326. end if;
  327. end loop;
  328. else
  329. for n in t_tbl'First + 1 .. t_tbl'Last loop
  330. p := Menus.Items (m, n);
  331. if Value (p) then
  332. Set_Value (Menus.Items (m, 1), False);
  333. changed := True;
  334. exit;
  335. end if;
  336. end loop;
  337. end if;
  338. if not changed then
  339. return True;
  340. end if;
  341. end case;
  342. end loop;
  343. end run_trace_menu;
  344. nc_tracing, mask : Trace_Attribute_Set;
  345. pragma Import (C, nc_tracing, "_nc_tracing");
  346. items_a : constant Item_Array_Access :=
  347. new Item_Array (t_tbl'First .. t_tbl'Last + 1);
  348. mrows : Line_Count;
  349. mcols : Column_Count;
  350. menuwin : Window;
  351. menu_y : constant Line_Position := 8;
  352. menu_x : constant Column_Position := 8;
  353. ip : Item;
  354. m : Menu;
  355. count : Integer;
  356. newtrace : Trace_Attribute_Set;
  357. begin
  358. Add (Line => 0, Column => 0, Str => "Interactively set trace level:");
  359. Add (Line => 2, Column => 0,
  360. Str => " Press space bar to toggle a selection.");
  361. Add (Line => 3, Column => 0,
  362. Str => " Use up and down arrow to move the select bar.");
  363. Add (Line => 4, Column => 0,
  364. Str => " Press return to set the trace level.");
  365. Add (Line => 6, Column => 0, Str => "(Current trace level is ");
  366. Add (Str => tracetrace (nc_tracing) & " numerically: " &
  367. trace_num (nc_tracing));
  368. Add (Ch => ')');
  369. Refresh;
  370. for n in t_tbl'Range loop
  371. items_a (n) := New_Item (t_tbl (n).name.all);
  372. end loop;
  373. items_a (t_tbl'Last + 1) := Null_Item;
  374. m := New_Menu (items_a);
  375. Set_Format (m, 16, 2);
  376. Scale (m, mrows, mcols);
  377. Switch_Options (m, (One_Valued => True, others => False), On => False);
  378. menuwin := New_Window (mrows + 2, mcols + 2, menu_y, menu_x);
  379. Set_Window (m, menuwin);
  380. Set_KeyPad_Mode (menuwin, SwitchOn => True);
  381. Box (menuwin);
  382. Set_Sub_Window (m, Derived_Window (menuwin, mrows, mcols, 1, 1));
  383. Post (m);
  384. for n in t_tbl'Range loop
  385. ip := Items (m, n);
  386. mask := t_tbl (n).mask;
  387. if mask = Trace_Disable then
  388. Set_Value (ip, nc_tracing = Trace_Disable);
  389. elsif subset (sub => mask, super => nc_tracing) then
  390. Set_Value (ip, True);
  391. end if;
  392. end loop;
  393. count := 1;
  394. while run_trace_menu (m, count) loop
  395. count := count + 1;
  396. end loop;
  397. newtrace := Trace_Disable;
  398. for n in t_tbl'Range loop
  399. ip := Items (m, n);
  400. if Value (ip) then
  401. mask := t_tbl (n).mask;
  402. newtrace := trace_or (newtrace, mask);
  403. end if;
  404. end loop;
  405. Trace_On (newtrace);
  406. Trace_Put ("trace level interactively set to " &
  407. tracetrace (nc_tracing));
  408. Move_Cursor (Line => Lines - 4, Column => 0);
  409. Add (Str => "Trace level is ");
  410. Add (Str => tracetrace (nc_tracing));
  411. Add (Ch => newl);
  412. Pause; -- was just Add(); Getchar
  413. Post (m, False);
  414. -- menuwin has subwindows I think, which makes an error.
  415. declare begin
  416. Delete (menuwin);
  417. exception when Curses_Exception => null; end;
  418. -- free_menu(m);
  419. -- free_item()
  420. end ncurses2.trace_set;