iup_get_param.e 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. class IUP_GET_PARAM
  2. -- Shows a modal dialog for capturing parameter values using several types of
  3. -- controls. After create the dialog with "get_param" you can add any
  4. -- amout of parameters with features "add_xxxx_parameter". The first
  5. -- argument in these features are the label of the parameter, you can
  6. -- add any number of characters %T at the label to indent the parameter entry.
  7. -- The argument "tip" is a string that is displayed as a tool-tip for the main
  8. -- control of the parameter. To add break lines in tool-tip string
  9. -- add the characters "%%r". You can pass an empty string if don't want a
  10. -- tool-tip. You can also add "separators" to organize the parameters.
  11. -- The dialog is resizable if it contains a string, a multiline string or a
  12. -- number with a valuator. All the multiline strings will increase size equally
  13. -- in both directions.
  14. --
  15. -- The dialog is resizable if it contains a string, a multiline string or a
  16. -- number with a valuator. All the multiline strings will increase size equally
  17. -- in both directions.
  18. --
  19. -- The dialog uses a global attribute called "PARENTDIALOG" as the parent
  20. -- dialog if it is defined. It also uses a global attribute called "ICON" as
  21. -- the dialog icon if it is defined.
  22. inherit
  23. IUP_WIDGET
  24. redefine
  25. execute_param
  26. end
  27. IUP_WIDGET_CUSTOM_ATTRIBUTES
  28. create {ANY}
  29. get_param
  30. feature {ANY}
  31. -- To store the default values at panel.
  32. pd: ARRAY[POINTER]
  33. get_param (title: STRING;
  34. act: FUNCTION[TUPLE[IUP_GET_PARAM, INTEGER, POINTER], INTEGER];
  35. user_data: POINTER)
  36. -- Create the dialog.
  37. --
  38. -- title: dialog title.
  39. -- act: user callback to be called whenever a parameter value was
  40. -- changed, and when the user pressed the OK button.
  41. -- user_data: user pointer passed to the user callback.
  42. --
  43. -- The callback receive three arguments:
  44. --
  45. -- dialog: the IUP_GET_PARAM object
  46. -- param_index: current parameter being changed. Can have negative values
  47. -- to indicate specific situations:
  48. -- -1 = if the user pressed the button 1.
  49. -- -2 = after the dialog is mapped and just before it is shown.
  50. -- -3 = if the user pressed the button 2.
  51. -- -4 = if the user pressed the button 3, if any.
  52. -- -5 = if the user clicked on the dialog close button.
  53. -- user_data: a user pointer that is passed in the function call.
  54. --
  55. -- Returns: You can reject the change or the button action by returning 0
  56. -- in the callback, otherwise you must return 1. By default button 1 and
  57. -- button 2 will close the dialog.
  58. --
  59. -- You should not programmatically change the current parameter value
  60. -- during the callback. On the other hand you can freely change the value
  61. -- of other parameters.
  62. do
  63. t := title
  64. cb_param := act
  65. ud := user_data
  66. pe := 0
  67. i := 1
  68. create f.make_empty
  69. create pd.make_empty
  70. end
  71. launch: INTEGER
  72. -- Show the dialog, return 1 if the button 1 was pressed, 0 if the button
  73. -- 2 was pressed or if an error occurred.
  74. local
  75. m: ARRAY[POINTER]
  76. x: INTEGER
  77. do
  78. iup_open.set_get_param (Current)
  79. x := 0
  80. create m.make_filled(default_pointer, 1, pd.count + 1)
  81. across
  82. pd as ic
  83. loop
  84. x := x + 1
  85. m.put(ic.item, x)
  86. end
  87. Result := int_get_param (get_pointer(t.to_c), ud,
  88. get_pointer(f.to_c), pd.count, pe,
  89. get_pointer(m.to_c))
  90. end
  91. -- Set parameters
  92. add_boolean_parameter (label, extra_data, tip: STRING; def: POINTER)
  93. -- Add an entry for a boolean parameter, it shows a True/False toggle.
  94. -- The "extra_data" parameter are optional strings, in the form
  95. -- "false_title,true_title" for boolean types to be displayed after the
  96. -- toggle. The strings can not have commas ',', nor brackets '[' or ']'.
  97. -- The "def" parameter should be a pointer to a integer with
  98. -- the initial value (0 for False and 1 to True).
  99. do
  100. f.append_string(label)
  101. f.append_string("%%b")
  102. if not extra_data.is_empty then
  103. f.append_string("[")
  104. f.append_string(extra_data)
  105. f.append_string("]")
  106. end
  107. if not tip.is_empty then
  108. f.append_string("{")
  109. f.append_string(tip)
  110. f.append_string("}")
  111. end
  112. f.append_string("%N")
  113. pd.force(def, i)
  114. i := i + 1
  115. end
  116. add_integer_parameter (label, extra_data, tip: STRING; def: POINTER)
  117. -- A field to a C integer value. The "extra_data" parameter is a
  118. -- string of the form "min,max,step". The "max" and "step" values can be
  119. -- omitted. When "min" and "max" are specified a valuator will also be
  120. -- added to change the value. To specify "step", "max" must be also
  121. -- specified. "step" is the size of the increment. The "def" parameter
  122. -- should be a pointer to a INTEGER with the initial value.
  123. -- A integer parameter always has a spin attached to the text to
  124. -- increment and decrement the value.
  125. do
  126. f.append_string(label)
  127. f.append_string("%%i")
  128. if not extra_data.is_empty then
  129. f.append_string("[")
  130. f.append_string(extra_data)
  131. f.append_string("]")
  132. end
  133. if not tip.is_empty then
  134. f.append_string("{")
  135. f.append_string(tip)
  136. f.append_string("}")
  137. end
  138. f.append_string("%N")
  139. pd.force(def, i)
  140. i := i + 1
  141. end
  142. add_real_parameter (label, extra_data, tip: STRING; def: POINTER)
  143. -- A field to a C real value. The "extra_data" parameter is a
  144. -- string of the form "min,max,step". The "max" and "step" values can be
  145. -- omitted. When "min" and "max" are specified a valuator will also be
  146. -- added to change the value. To specify "step", "max" must be also
  147. -- specified. "step" is the size of the increment. The "def" parameter
  148. -- should be a pointer to a REAL_32 with the initial value.
  149. -- A real parameter only has a spin in a full interval is defined (min
  150. -- and max), in this case the default step is (max-min)/20.
  151. do
  152. f.append_string(label)
  153. f.append_string("%%r")
  154. if not extra_data.is_empty then
  155. f.append_string("[")
  156. f.append_string(extra_data)
  157. f.append_string("]")
  158. end
  159. if not tip.is_empty then
  160. f.append_string("{")
  161. f.append_string(tip)
  162. f.append_string("}")
  163. end
  164. f.append_string("%N")
  165. pd.force(def, i)
  166. i := i + 1
  167. end
  168. add_double_parameter (label, extra_data, tip: STRING; def: POINTER)
  169. -- A field to a C double value. The "extra_data" parameter is a
  170. -- string of the form "min,max,step". The "max" and "step" values can be
  171. -- omitted. When "min" and "max" are specified a valuator will also be
  172. -- added to change the value. To specify "step", "max" must be also
  173. -- specified. "step" is the size of the increment. The "def" parameter
  174. -- should be a pointer to a REAL_64 with the initial value.
  175. -- A double parameter only has a spin in a full interval is defined (min
  176. -- and max), in this case the default step is (max-min)/20.
  177. do
  178. f.append_string(label)
  179. f.append_string("%%R")
  180. if not extra_data.is_empty then
  181. f.append_string("[")
  182. f.append_string(extra_data)
  183. f.append_string("]")
  184. end
  185. if not tip.is_empty then
  186. f.append_string("{")
  187. f.append_string(tip)
  188. f.append_string("}")
  189. end
  190. f.append_string("%N")
  191. pd.force(def, i)
  192. i := i + 1
  193. end
  194. add_angle_real_parameter (label, extra_data, tip: STRING; def: POINTER)
  195. -- A field to a C real value. The "extra_data" parameter is a
  196. -- string of the form "min,max,step". The "max" and "step" values can be
  197. -- omitted. When "min" and "max" are specified a dial will also be
  198. -- added to change the value (only if "load_iup_controls" is
  199. -- called on IUP). To specify "step", "max" must be also
  200. -- specified. "step" is the size of the increment. The "def" parameter
  201. -- should be a pointer to a REAL_32 with the initial value.
  202. do
  203. f.append_string(label)
  204. f.append_string("%%a")
  205. if not extra_data.is_empty then
  206. f.append_string("[")
  207. f.append_string(extra_data)
  208. f.append_string("]")
  209. end
  210. if not tip.is_empty then
  211. f.append_string("{")
  212. f.append_string(tip)
  213. f.append_string("}")
  214. end
  215. f.append_string("%N")
  216. pd.force(def, i)
  217. i := i + 1
  218. end
  219. add_angle_double_parameter (label, extra_data, tip: STRING; def: POINTER)
  220. -- A field to an C double value. The "extra_data" parameter is a
  221. -- string of the form "min,max,step". The "max" and "step" values can be
  222. -- omitted. When "min" and "max" are specified a dial will also be
  223. -- added to change the value (only if "load_iup_controls" is
  224. -- called on IUP). To specify "step", "max" must be also
  225. -- specified. "step" is the size of the increment. The "def" parameter
  226. -- should be a pointer to a REAL_64 with the initial value.
  227. do
  228. f.append_string(label)
  229. f.append_string("%%A")
  230. if not extra_data.is_empty then
  231. f.append_string("[")
  232. f.append_string(extra_data)
  233. f.append_string("]")
  234. end
  235. if not tip.is_empty then
  236. f.append_string("{")
  237. f.append_string(tip)
  238. f.append_string("}")
  239. end
  240. f.append_string("%N")
  241. pd.force(def, i)
  242. i := i + 1
  243. end
  244. add_string_parameter (label, extra_data, tip: STRING; def: POINTER)
  245. -- A field to a string value. The "extra_data" parameter is an optional
  246. -- mask for the string. The maks have the same format used in IUP_TEXT.
  247. -- For more information see:
  248. -- http://webserver2.tecgraf.puc-rio.br/iup/en/attrib/iup_mask.html
  249. -- Pass an empty string if don't want a mask.
  250. -- The "def" parameter should be a pointer to a STRING with the initial
  251. -- value (if any) and with enough space for the user entry.
  252. do
  253. f.append_string(label)
  254. f.append_string("%%s")
  255. if not extra_data.is_empty then
  256. f.append_string("[")
  257. f.append_string(extra_data)
  258. f.append_string("]")
  259. end
  260. if not tip.is_empty then
  261. f.append_string("{")
  262. f.append_string(tip)
  263. f.append_string("}")
  264. end
  265. f.append_string("%N")
  266. pd.force(def, i)
  267. i := i + 1
  268. end
  269. add_multiline_parameter (label, extra_data, tip: STRING; def: POINTER)
  270. -- A field to a multiline string value. The "extra_data" parameter is an
  271. -- optional mask for the string. The maks have the same format used in
  272. -- IUP_TEXT. For more information see:
  273. -- http://webserver2.tecgraf.puc-rio.br/iup/en/attrib/iup_mask.html
  274. -- Pass an empty string if don't want a mask.
  275. -- The "def" parameter should be a pointer to a STRING with the initial
  276. -- value (if any) and with enough space for the user entry.
  277. do
  278. f.append_string(label)
  279. f.append_string("%%m")
  280. if not extra_data.is_empty then
  281. f.append_string("[")
  282. f.append_string(extra_data)
  283. f.append_string("]")
  284. end
  285. if not tip.is_empty then
  286. f.append_string("{")
  287. f.append_string(tip)
  288. f.append_string("}")
  289. end
  290. f.append_string("%N")
  291. pd.force(def, i)
  292. i := i + 1
  293. end
  294. add_list_parameter (label, extra_data, tip: STRING; def: POINTER)
  295. -- A dropdown list box. The "extra_data" parameter is a string of the
  296. -- form "item0|item1|item2|...|itemN" with the titles of the items in the
  297. -- list. At least one item must exist. Items index are zero based start.
  298. -- The "def" parameter should be a pointer to an INTEGER with
  299. -- the initial value (the selected item).
  300. do
  301. f.append_string(label)
  302. f.append_string("%%l")
  303. if not extra_data.is_empty then
  304. f.append_string("|")
  305. f.append_string(extra_data)
  306. f.append_string("|")
  307. end
  308. if not tip.is_empty then
  309. f.append_string("{")
  310. f.append_string(tip)
  311. f.append_string("}")
  312. end
  313. f.append_string("%N")
  314. pd.force(def, i)
  315. i := i + 1
  316. end
  317. add_radio_parameter (label, extra_data, tip: STRING; def: POINTER)
  318. -- A list of toggles inside a radio. The "extra_data" parameter is a
  319. -- string of the form "item0|item1|item2|...|itemN" with
  320. -- the titles of the items in the list. At least one item must exist.
  321. -- Items index are zero based start. The "def" parameter should be a
  322. -- pointer to an INTEGER with the initial value (the selected item).
  323. do
  324. f.append_string(label)
  325. f.append_string("%%o")
  326. if not extra_data.is_empty then
  327. f.append_string("|")
  328. f.append_string(extra_data)
  329. f.append_string("|")
  330. end
  331. if not tip.is_empty then
  332. f.append_string("{")
  333. f.append_string(tip)
  334. f.append_string("}")
  335. end
  336. f.append_string("%N")
  337. pd.force(def, i)
  338. i := i + 1
  339. end
  340. add_separator (label: STRING)
  341. -- Separator. Shows a horizontal line separator label, in this case text
  342. -- can be an empty string.
  343. do
  344. f.append_string(label)
  345. f.append_string("%%t")
  346. f.append_string("%N")
  347. pe := pe + 1
  348. end
  349. add_date_parameter (label, extra_data, tip: STRING; def: POINTER)
  350. -- A string parameter, but the interface uses a IUP_DATE_PICK element to
  351. -- select a date. The "extra_data" parameter are simply IUP_DATE_PICK
  352. -- attributes in a single string. The "def" parameter should be a pointer
  353. -- to a string with the initial value and with enough space for the user
  354. -- entry.
  355. do
  356. f.append_string(label)
  357. f.append_string("%%d")
  358. if not extra_data.is_empty then
  359. f.append_string("|")
  360. f.append_string(extra_data)
  361. f.append_string("|")
  362. end
  363. if not tip.is_empty then
  364. f.append_string("{")
  365. f.append_string(tip)
  366. f.append_string("}")
  367. end
  368. f.append_string("%N")
  369. pd.force(def, i)
  370. i := i + 1
  371. end
  372. add_file_parameter (label, extra_data, tip: STRING; def: POINTER)
  373. -- A string parameter with a button to open a file selection dialog box.
  374. -- The "estra_data" is a string of the form
  375. -- "dialogtype|filter|directory|nochangedir|nooverwriteprompt"
  376. -- with the respective attribute values passed to the IUP_FILE_DIALOG
  377. -- control when activated. All '|' must exist, but you can let empty
  378. -- values to use the default values.
  379. -- The "def" parameter should be a pointer to a string with the
  380. -- initial value and with enough space for the user entry.
  381. do
  382. f.append_string(label)
  383. f.append_string("%%f")
  384. if not tip.is_empty then
  385. f.append_string("{")
  386. f.append_string(tip)
  387. f.append_string("}")
  388. end
  389. f.append_string("%N")
  390. pd.force(def, i)
  391. i := i + 1
  392. end
  393. add_color_parameter (label, tip: STRING; def: POINTER)
  394. -- A string parameter with a color button to open a color selection
  395. -- dialog box. The "def" parameter should be a pointer to a string
  396. -- with the initial value and with enough space for the user entry.
  397. do
  398. f.append_string(label)
  399. f.append_string("%%c")
  400. if not tip.is_empty then
  401. f.append_string("{")
  402. f.append_string(tip)
  403. f.append_string("}")
  404. end
  405. f.append_string("%N")
  406. pd.force(def, i)
  407. i := i + 1
  408. end
  409. add_font_parameter (label, tip: STRING; def: POINTER)
  410. -- A string parameter with a font button to open a font selection
  411. -- dialog box. The "def" parameter should be a pointer to a string
  412. -- with the initial value and with enough space for the user entry.
  413. do
  414. f.append_string(label)
  415. f.append_string("%%n")
  416. if not tip.is_empty then
  417. f.append_string("{")
  418. f.append_string(tip)
  419. f.append_string("}")
  420. end
  421. f.append_string("%N")
  422. pd.force(def, i)
  423. i := i + 1
  424. end
  425. add_widget_parameter (label: STRING; wgt: IUP_WIDGET)
  426. -- Add a widget that will be managed by the application, it will be
  427. -- placed after the parameters and before the buttons
  428. do
  429. f.append_string(label)
  430. f.append_string("%%h")
  431. f.append_string("%N")
  432. pd.force(wgt.widget, i)
  433. i := i + 1
  434. end
  435. add_buttons_parameter (titles: STRING)
  436. -- Buttons titles. Allow to redefine the default button titles (OK and
  437. -- Cancel), and to add a third button. Use "button1,button2,button3".
  438. -- Can omit one of them, it will use the default name.
  439. do
  440. f.append_string("Bt %%u")
  441. f.append_string("[")
  442. f.append_string(titles)
  443. f.append_string("]")
  444. f.append_string("%N")
  445. pe := pe + 1
  446. end
  447. -- Attributes
  448. set_precision (decimals: INTEGER)
  449. -- The default number of decimal places used in floating point output by
  450. -- some controls.
  451. --
  452. -- The default precision for real value display is given by the global
  453. -- attribute DEFAULTPRECISION. But inside the callback the application
  454. -- can use this feature to use another value. It will work only during
  455. -- interactive changes. The decimal symbol will used the
  456. -- DEFAULTDECIMALSYMBOL global attribute. Local attributes may overwrite
  457. -- the default. Default: 2.
  458. require
  459. decimals >= 0
  460. do
  461. iup_open.set_attribute (Current, "PRECISION", decimals.out)
  462. end
  463. get_button (number: INTEGER): IUP_BUTTON
  464. -- Returns the button 1, 2 or 3 (if any).
  465. require
  466. number >= 1
  467. number <= 3
  468. local
  469. p: POINTER
  470. b: IUP_BUTTON
  471. do
  472. if number.is_equal(1) then
  473. p := iup_open.get_attribute_ihandle(Current, "BUTTON1")
  474. elseif number.is_equal(2) then
  475. p := iup_open.get_attribute_ihandle(Current, "BUTTON2")
  476. elseif number.is_equal(3) then
  477. p := iup_open.get_attribute_ihandle(Current, "BUTTON3")
  478. end
  479. create b.button_widget(p)
  480. Result := b
  481. end
  482. --get_parameter_label_at (number: INTEGER): IUP_LABEL
  483. -- local
  484. -- str: STRING
  485. -- a_label: IUP_LABEL
  486. -- p1, p2: POINTER
  487. -- do
  488. -- str := "PARAM"
  489. -- str.append_string(number.out)
  490. -- p1 := iup_open.get_attribute_ihandle(Current, str)
  491. -- p2 := iup_open.get_attribute_ihandle_from_handle(p1, str)
  492. --
  493. -- create a_label.label_widget(p2)
  494. -- Result := a_label
  495. -- end
  496. get_parameter_value_at (index: INTEGER): STRING
  497. -- Get the value, as string, that the user writes in the parameter at
  498. -- provided index.
  499. local
  500. p: POINTER
  501. str: STRING
  502. do
  503. str := "PARAM"
  504. str.append_string(index.out)
  505. p := iup_open.get_attribute_ihandle(Current, str)
  506. if p /= default_pointer then
  507. Result := iup_open.get_attribute_from_handle(p, "VALUE")
  508. else
  509. Result := ""
  510. end
  511. end
  512. set_parameter_value_at (value: STRING; index: INTEGER)
  513. -- Set the value, passed as string, in the parameter at provided index.
  514. -- This set the value at the control and at the auxiliary
  515. -- control (if any).
  516. local
  517. str: STRING
  518. p1, p2: POINTER
  519. do
  520. str := "PARAM"
  521. str.append_string(index.out)
  522. p1 := iup_open.get_attribute_ihandle(Current, str)
  523. if p1 /= default_pointer then
  524. iup_open.set_attribute_in_handle(p1, "VALUE", value)
  525. end
  526. p2 := iup_open.get_attribute_ihandle_from_handle(p1, "AUXCONTROL")
  527. if p2 /= default_pointer then
  528. iup_open.set_attribute_in_handle(p2, "VALUE", value)
  529. end
  530. end
  531. set_parameter_visible_columns_at (value, index: INTEGER)
  532. -- Set the visible columns in string parameters (those
  533. -- added with "add_string_parameter").
  534. local
  535. str: STRING
  536. p: POINTER
  537. do
  538. str := "PARAM"
  539. str.append_string(index.out)
  540. p := iup_open.get_attribute_ihandle(Current, str)
  541. if p /= default_pointer then
  542. iup_open.set_attribute_in_handle(p, "VISIBLECOLUMNS",
  543. value.out)
  544. end
  545. end
  546. get_spinning: INTEGER
  547. -- A integer parameter always has a spin attached to the text to
  548. -- increment and decrement the value. A real parameter only has a spin in
  549. -- a full interval is defined (min and max), in this case the default
  550. -- step is (max-min)/20. When the callback is called because a spin was
  551. -- activated then this feature return a non zero value.
  552. local
  553. str: STRING
  554. do
  555. str := iup_open.get_attribute (Current, "SPINNING")
  556. if str /= Void then
  557. if str.is_integer then
  558. Result := str.to_integer
  559. end
  560. end
  561. end
  562. feature {IUP}
  563. execute_param (handle: POINTER; param_index: INTEGER; user_data: POINTER): INTEGER
  564. do
  565. if attached cb_param as int_cb then
  566. widget := handle
  567. Result := int_cb.item([Current, param_index, user_data])
  568. else
  569. Result := 0
  570. end
  571. end
  572. feature {NONE}
  573. cb_param: detachable FUNCTION[TUPLE[IUP_GET_PARAM, INTEGER, POINTER], INTEGER]
  574. t, f: STRING
  575. ud: POINTER
  576. pe: INTEGER
  577. i: INTEGER
  578. -- Internals
  579. int_get_param (title, user_data, format: POINTER; param_count, param_extra: INTEGER; param_data: POINTER): INTEGER
  580. external
  581. "C inline use %"eiffel-iup.h%""
  582. alias
  583. "return get_param_dialog ($title, $user_data, $format, $param_count, $param_extra, $param_data);"
  584. end
  585. end -- end class
  586. -- The MIT License (MIT)
  587. -- Copyright (c) 2016, 2017, 2019, 2020 by German A. Arias
  588. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  589. -- of this software and associated documentation files (the "Software"), to deal
  590. -- in the Software without restriction, including without limitation the rights
  591. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  592. -- copies of the Software, and to permit persons to whom the Software is
  593. -- furnished to do so, subject to the following conditions:
  594. --
  595. -- The above copyright notice and this permission notice shall be included in
  596. -- all copies or substantial portions of the Software.
  597. --
  598. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  599. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  600. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  601. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  602. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  603. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  604. -- SOFTWARE.