PageRenderTime 54ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/freebsd4/sys/boot/forth/support.4th

https://github.com/kame/kame
Forth | 1131 lines | 969 code | 162 blank | 0 comment | 80 complexity | 263f1e8f5fc187b5cafc935919960e64 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0
  1. \ Copyright (c) 1999 Daniel C. Sobral <dcs@freebsd.org>
  2. \ All rights reserved.
  3. \
  4. \ Redistribution and use in source and binary forms, with or without
  5. \ modification, are permitted provided that the following conditions
  6. \ are met:
  7. \ 1. Redistributions of source code must retain the above copyright
  8. \ notice, this list of conditions and the following disclaimer.
  9. \ 2. Redistributions in binary form must reproduce the above copyright
  10. \ notice, this list of conditions and the following disclaimer in the
  11. \ documentation and/or other materials provided with the distribution.
  12. \
  13. \ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  14. \ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. \ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  16. \ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  17. \ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. \ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  19. \ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  20. \ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21. \ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22. \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  23. \ SUCH DAMAGE.
  24. \
  25. \ $FreeBSD: src/sys/boot/forth/support.4th,v 1.3 1999/11/24 17:56:40 dcs Exp $
  26. \ Loader.rc support functions:
  27. \
  28. \ initialize_support ( -- ) initialize global variables
  29. \ initialize ( addr len -- ) as above, plus load_conf_files
  30. \ load_conf ( addr len -- ) load conf file given
  31. \ include_conf_files ( -- ) load all conf files in load_conf_files
  32. \ print_syntax_error ( -- ) print line and marker of where a syntax
  33. \ error was detected
  34. \ print_line ( -- ) print last line processed
  35. \ load_kernel ( -- ) load kernel
  36. \ load_modules ( -- ) load modules flagged
  37. \
  38. \ Exported structures:
  39. \
  40. \ string counted string structure
  41. \ cell .addr string address
  42. \ cell .len string length
  43. \ module module loading information structure
  44. \ cell module.flag should we load it?
  45. \ string module.name module's name
  46. \ string module.loadname name to be used in loading the module
  47. \ string module.type module's type
  48. \ string module.args flags to be passed during load
  49. \ string module.beforeload command to be executed before load
  50. \ string module.afterload command to be executed after load
  51. \ string module.loaderror command to be executed if load fails
  52. \ cell module.next list chain
  53. \
  54. \ Exported global variables;
  55. \
  56. \ string conf_files configuration files to be loaded
  57. \ string password password
  58. \ cell modules_options pointer to first module information
  59. \ value verbose? indicates if user wants a verbose loading
  60. \ value any_conf_read? indicates if a conf file was succesfully read
  61. \
  62. \ Other exported words:
  63. \
  64. \ strdup ( addr len -- addr' len) similar to strdup(3)
  65. \ strcat ( addr len addr' len' -- addr len+len' ) similar to strcat(3)
  66. \ s' ( | string' -- addr len | ) similar to s"
  67. \ rudimentary structure support
  68. \ Exception values
  69. 1 constant syntax_error
  70. 2 constant out_of_memory
  71. 3 constant free_error
  72. 4 constant set_error
  73. 5 constant read_error
  74. 6 constant open_error
  75. 7 constant exec_error
  76. 8 constant before_load_error
  77. 9 constant after_load_error
  78. \ Crude structure support
  79. : structure: create here 0 , 0 does> create @ allot ;
  80. : member: create dup , over , + does> cell+ @ + ;
  81. : ;structure swap ! ;
  82. : sizeof ' >body @ state @ if postpone literal then ; immediate
  83. : offsetof ' >body cell+ @ state @ if postpone literal then ; immediate
  84. : ptr 1 cells member: ;
  85. : int 1 cells member: ;
  86. \ String structure
  87. structure: string
  88. ptr .addr
  89. int .len
  90. ;structure
  91. \ Module options linked list
  92. structure: module
  93. int module.flag
  94. sizeof string member: module.name
  95. sizeof string member: module.loadname
  96. sizeof string member: module.type
  97. sizeof string member: module.args
  98. sizeof string member: module.beforeload
  99. sizeof string member: module.afterload
  100. sizeof string member: module.loaderror
  101. ptr module.next
  102. ;structure
  103. \ Global variables
  104. string conf_files
  105. string password
  106. create module_options sizeof module.next allot
  107. create last_module_option sizeof module.next allot
  108. 0 value verbose?
  109. \ Support string functions
  110. : strdup ( addr len -- addr' len )
  111. >r r@ allocate if out_of_memory throw then
  112. tuck r@ move
  113. r>
  114. ;
  115. : strcat { addr len addr' len' -- addr len+len' }
  116. addr' addr len + len' move
  117. addr len len' +
  118. ;
  119. : s'
  120. [char] ' parse
  121. state @ if
  122. postpone sliteral
  123. then
  124. ; immediate
  125. \ How come ficl doesn't have again?
  126. : again false postpone literal postpone until ; immediate
  127. \ Private definitions
  128. vocabulary support-functions
  129. only forth also support-functions definitions
  130. \ Some control characters constants
  131. 7 constant bell
  132. 8 constant backspace
  133. 9 constant tab
  134. 10 constant lf
  135. 13 constant <cr>
  136. \ Read buffer size
  137. 80 constant read_buffer_size
  138. \ Standard suffixes
  139. : load_module_suffix s" _load" ;
  140. : module_loadname_suffix s" _name" ;
  141. : module_type_suffix s" _type" ;
  142. : module_args_suffix s" _flags" ;
  143. : module_beforeload_suffix s" _before" ;
  144. : module_afterload_suffix s" _after" ;
  145. : module_loaderror_suffix s" _error" ;
  146. \ Support operators
  147. : >= < 0= ;
  148. : <= > 0= ;
  149. \ Assorted support funcitons
  150. : free-memory free if free_error throw then ;
  151. \ Assignment data temporary storage
  152. string name_buffer
  153. string value_buffer
  154. \ File data temporary storage
  155. string line_buffer
  156. string read_buffer
  157. 0 value read_buffer_ptr
  158. \ File's line reading function
  159. 0 value end_of_file?
  160. variable fd
  161. : skip_newlines
  162. begin
  163. read_buffer .len @ read_buffer_ptr >
  164. while
  165. read_buffer .addr @ read_buffer_ptr + c@ lf = if
  166. read_buffer_ptr char+ to read_buffer_ptr
  167. else
  168. exit
  169. then
  170. repeat
  171. ;
  172. : scan_buffer ( -- addr len )
  173. read_buffer_ptr >r
  174. begin
  175. read_buffer .len @ r@ >
  176. while
  177. read_buffer .addr @ r@ + c@ lf = if
  178. read_buffer .addr @ read_buffer_ptr + ( -- addr )
  179. r@ read_buffer_ptr - ( -- len )
  180. r> to read_buffer_ptr
  181. exit
  182. then
  183. r> char+ >r
  184. repeat
  185. read_buffer .addr @ read_buffer_ptr + ( -- addr )
  186. r@ read_buffer_ptr - ( -- len )
  187. r> to read_buffer_ptr
  188. ;
  189. : line_buffer_resize ( len -- len )
  190. >r
  191. line_buffer .len @ if
  192. line_buffer .addr @
  193. line_buffer .len @ r@ +
  194. resize if out_of_memory throw then
  195. else
  196. r@ allocate if out_of_memory throw then
  197. then
  198. line_buffer .addr !
  199. r>
  200. ;
  201. : append_to_line_buffer ( addr len -- )
  202. line_buffer .addr @ line_buffer .len @
  203. 2swap strcat
  204. line_buffer .len !
  205. drop
  206. ;
  207. : read_from_buffer
  208. scan_buffer ( -- addr len )
  209. line_buffer_resize ( len -- len )
  210. append_to_line_buffer ( addr len -- )
  211. ;
  212. : refill_required?
  213. read_buffer .len @ read_buffer_ptr =
  214. end_of_file? 0= and
  215. ;
  216. : refill_buffer
  217. 0 to read_buffer_ptr
  218. read_buffer .addr @ 0= if
  219. read_buffer_size allocate if out_of_memory throw then
  220. read_buffer .addr !
  221. then
  222. fd @ read_buffer .addr @ read_buffer_size fread
  223. dup -1 = if read_error throw then
  224. dup 0= if true to end_of_file? then
  225. read_buffer .len !
  226. ;
  227. : reset_line_buffer
  228. 0 line_buffer .addr !
  229. 0 line_buffer .len !
  230. ;
  231. : read_line
  232. reset_line_buffer
  233. skip_newlines
  234. begin
  235. read_from_buffer
  236. refill_required?
  237. while
  238. refill_buffer
  239. repeat
  240. ;
  241. \ Conf file line parser:
  242. \ <line> ::= <spaces><name><spaces>'='<spaces><value><spaces>[<comment>] |
  243. \ <spaces>[<comment>]
  244. \ <name> ::= <letter>{<letter>|<digit>|'_'}
  245. \ <value> ::= '"'{<character_set>|'\'<anything>}'"' | <name>
  246. \ <character_set> ::= ASCII 32 to 126, except '\' and '"'
  247. \ <comment> ::= '#'{<anything>}
  248. 0 value parsing_function
  249. 0 value end_of_line
  250. 0 value line_pointer
  251. : end_of_line?
  252. line_pointer end_of_line =
  253. ;
  254. : letter?
  255. line_pointer c@ >r
  256. r@ [char] A >=
  257. r@ [char] Z <= and
  258. r@ [char] a >=
  259. r> [char] z <= and
  260. or
  261. ;
  262. : digit?
  263. line_pointer c@ >r
  264. r@ [char] 0 >=
  265. r> [char] 9 <= and
  266. ;
  267. : quote?
  268. line_pointer c@ [char] " =
  269. ;
  270. : assignment_sign?
  271. line_pointer c@ [char] = =
  272. ;
  273. : comment?
  274. line_pointer c@ [char] # =
  275. ;
  276. : space?
  277. line_pointer c@ bl =
  278. line_pointer c@ tab = or
  279. ;
  280. : backslash?
  281. line_pointer c@ [char] \ =
  282. ;
  283. : underscore?
  284. line_pointer c@ [char] _ =
  285. ;
  286. : dot?
  287. line_pointer c@ [char] . =
  288. ;
  289. : skip_character
  290. line_pointer char+ to line_pointer
  291. ;
  292. : skip_to_end_of_line
  293. end_of_line to line_pointer
  294. ;
  295. : eat_space
  296. begin
  297. space?
  298. while
  299. skip_character
  300. end_of_line? if exit then
  301. repeat
  302. ;
  303. : parse_name ( -- addr len )
  304. line_pointer
  305. begin
  306. letter? digit? underscore? dot? or or or
  307. while
  308. skip_character
  309. end_of_line? if
  310. line_pointer over -
  311. strdup
  312. exit
  313. then
  314. repeat
  315. line_pointer over -
  316. strdup
  317. ;
  318. : remove_backslashes { addr len | addr' len' -- addr' len' }
  319. len allocate if out_of_memory throw then
  320. to addr'
  321. addr >r
  322. begin
  323. addr c@ [char] \ <> if
  324. addr c@ addr' len' + c!
  325. len' char+ to len'
  326. then
  327. addr char+ to addr
  328. r@ len + addr =
  329. until
  330. r> drop
  331. addr' len'
  332. ;
  333. : parse_quote ( -- addr len )
  334. line_pointer
  335. skip_character
  336. end_of_line? if syntax_error throw then
  337. begin
  338. quote? 0=
  339. while
  340. backslash? if
  341. skip_character
  342. end_of_line? if syntax_error throw then
  343. then
  344. skip_character
  345. end_of_line? if syntax_error throw then
  346. repeat
  347. skip_character
  348. line_pointer over -
  349. remove_backslashes
  350. ;
  351. : read_name
  352. parse_name ( -- addr len )
  353. name_buffer .len !
  354. name_buffer .addr !
  355. ;
  356. : read_value
  357. quote? if
  358. parse_quote ( -- addr len )
  359. else
  360. parse_name ( -- addr len )
  361. then
  362. value_buffer .len !
  363. value_buffer .addr !
  364. ;
  365. : comment
  366. skip_to_end_of_line
  367. ;
  368. : white_space_4
  369. eat_space
  370. comment? if ['] comment to parsing_function exit then
  371. end_of_line? 0= if syntax_error throw then
  372. ;
  373. : variable_value
  374. read_value
  375. ['] white_space_4 to parsing_function
  376. ;
  377. : white_space_3
  378. eat_space
  379. letter? digit? quote? or or if
  380. ['] variable_value to parsing_function exit
  381. then
  382. syntax_error throw
  383. ;
  384. : assignment_sign
  385. skip_character
  386. ['] white_space_3 to parsing_function
  387. ;
  388. : white_space_2
  389. eat_space
  390. assignment_sign? if ['] assignment_sign to parsing_function exit then
  391. syntax_error throw
  392. ;
  393. : variable_name
  394. read_name
  395. ['] white_space_2 to parsing_function
  396. ;
  397. : white_space_1
  398. eat_space
  399. letter? if ['] variable_name to parsing_function exit then
  400. comment? if ['] comment to parsing_function exit then
  401. end_of_line? 0= if syntax_error throw then
  402. ;
  403. : get_assignment
  404. line_buffer .addr @ line_buffer .len @ + to end_of_line
  405. line_buffer .addr @ to line_pointer
  406. ['] white_space_1 to parsing_function
  407. begin
  408. end_of_line? 0=
  409. while
  410. parsing_function execute
  411. repeat
  412. parsing_function ['] comment =
  413. parsing_function ['] white_space_1 =
  414. parsing_function ['] white_space_4 =
  415. or or 0= if syntax_error throw then
  416. ;
  417. \ Process line
  418. : assignment_type? ( addr len -- flag )
  419. name_buffer .addr @ name_buffer .len @
  420. compare 0=
  421. ;
  422. : suffix_type? ( addr len -- flag )
  423. name_buffer .len @ over <= if 2drop false exit then
  424. name_buffer .len @ over - name_buffer .addr @ +
  425. over compare 0=
  426. ;
  427. : loader_conf_files?
  428. s" loader_conf_files" assignment_type?
  429. ;
  430. : verbose_flag?
  431. s" verbose_loading" assignment_type?
  432. ;
  433. : execute?
  434. s" exec" assignment_type?
  435. ;
  436. : password?
  437. s" password" assignment_type?
  438. ;
  439. : module_load?
  440. load_module_suffix suffix_type?
  441. ;
  442. : module_loadname?
  443. module_loadname_suffix suffix_type?
  444. ;
  445. : module_type?
  446. module_type_suffix suffix_type?
  447. ;
  448. : module_args?
  449. module_args_suffix suffix_type?
  450. ;
  451. : module_beforeload?
  452. module_beforeload_suffix suffix_type?
  453. ;
  454. : module_afterload?
  455. module_afterload_suffix suffix_type?
  456. ;
  457. : module_loaderror?
  458. module_loaderror_suffix suffix_type?
  459. ;
  460. : set_conf_files
  461. conf_files .addr @ ?dup if
  462. free-memory
  463. then
  464. value_buffer .addr @ c@ [char] " = if
  465. value_buffer .addr @ char+ value_buffer .len @ 2 chars -
  466. else
  467. value_buffer .addr @ value_buffer .len @
  468. then
  469. strdup
  470. conf_files .len ! conf_files .addr !
  471. ;
  472. : append_to_module_options_list ( addr -- )
  473. module_options @ 0= if
  474. dup module_options !
  475. last_module_option !
  476. else
  477. dup last_module_option @ module.next !
  478. last_module_option !
  479. then
  480. ;
  481. : set_module_name ( addr -- )
  482. name_buffer .addr @ name_buffer .len @
  483. strdup
  484. >r over module.name .addr !
  485. r> swap module.name .len !
  486. ;
  487. : yes_value?
  488. value_buffer .addr @ value_buffer .len @
  489. 2dup s' "YES"' compare >r
  490. 2dup s' "yes"' compare >r
  491. 2dup s" YES" compare >r
  492. s" yes" compare r> r> r> and and and 0=
  493. ;
  494. : find_module_option ( -- addr | 0 )
  495. module_options @
  496. begin
  497. dup
  498. while
  499. dup module.name dup .addr @ swap .len @
  500. name_buffer .addr @ name_buffer .len @
  501. compare 0= if exit then
  502. module.next @
  503. repeat
  504. ;
  505. : new_module_option ( -- addr )
  506. sizeof module allocate if out_of_memory throw then
  507. dup sizeof module erase
  508. dup append_to_module_options_list
  509. dup set_module_name
  510. ;
  511. : get_module_option ( -- addr )
  512. find_module_option
  513. ?dup 0= if new_module_option then
  514. ;
  515. : set_module_flag
  516. name_buffer .len @ load_module_suffix nip - name_buffer .len !
  517. yes_value? get_module_option module.flag !
  518. ;
  519. : set_module_args
  520. name_buffer .len @ module_args_suffix nip - name_buffer .len !
  521. get_module_option module.args
  522. dup .addr @ ?dup if free-memory then
  523. value_buffer .addr @ value_buffer .len @
  524. over c@ [char] " = if
  525. 2 chars - swap char+ swap
  526. then
  527. strdup
  528. >r over .addr !
  529. r> swap .len !
  530. ;
  531. : set_module_loadname
  532. name_buffer .len @ module_loadname_suffix nip - name_buffer .len !
  533. get_module_option module.loadname
  534. dup .addr @ ?dup if free-memory then
  535. value_buffer .addr @ value_buffer .len @
  536. over c@ [char] " = if
  537. 2 chars - swap char+ swap
  538. then
  539. strdup
  540. >r over .addr !
  541. r> swap .len !
  542. ;
  543. : set_module_type
  544. name_buffer .len @ module_type_suffix nip - name_buffer .len !
  545. get_module_option module.type
  546. dup .addr @ ?dup if free-memory then
  547. value_buffer .addr @ value_buffer .len @
  548. over c@ [char] " = if
  549. 2 chars - swap char+ swap
  550. then
  551. strdup
  552. >r over .addr !
  553. r> swap .len !
  554. ;
  555. : set_module_beforeload
  556. name_buffer .len @ module_beforeload_suffix nip - name_buffer .len !
  557. get_module_option module.beforeload
  558. dup .addr @ ?dup if free-memory then
  559. value_buffer .addr @ value_buffer .len @
  560. over c@ [char] " = if
  561. 2 chars - swap char+ swap
  562. then
  563. strdup
  564. >r over .addr !
  565. r> swap .len !
  566. ;
  567. : set_module_afterload
  568. name_buffer .len @ module_afterload_suffix nip - name_buffer .len !
  569. get_module_option module.afterload
  570. dup .addr @ ?dup if free-memory then
  571. value_buffer .addr @ value_buffer .len @
  572. over c@ [char] " = if
  573. 2 chars - swap char+ swap
  574. then
  575. strdup
  576. >r over .addr !
  577. r> swap .len !
  578. ;
  579. : set_module_loaderror
  580. name_buffer .len @ module_loaderror_suffix nip - name_buffer .len !
  581. get_module_option module.loaderror
  582. dup .addr @ ?dup if free-memory then
  583. value_buffer .addr @ value_buffer .len @
  584. over c@ [char] " = if
  585. 2 chars - swap char+ swap
  586. then
  587. strdup
  588. >r over .addr !
  589. r> swap .len !
  590. ;
  591. : set_environment_variable
  592. name_buffer .len @
  593. value_buffer .len @ +
  594. 5 chars +
  595. allocate if out_of_memory throw then
  596. dup 0 ( addr -- addr addr len )
  597. s" set " strcat
  598. name_buffer .addr @ name_buffer .len @ strcat
  599. s" =" strcat
  600. value_buffer .addr @ value_buffer .len @ strcat
  601. ['] evaluate catch if
  602. 2drop free drop
  603. set_error throw
  604. else
  605. free-memory
  606. then
  607. ;
  608. : set_verbose
  609. yes_value? to verbose?
  610. ;
  611. : execute_command
  612. value_buffer .addr @ value_buffer .len @
  613. over c@ [char] " = if
  614. 2 - swap char+ swap
  615. then
  616. ['] evaluate catch if exec_error throw then
  617. ;
  618. : set_password
  619. password .addr @ ?dup if free if free_error throw then then
  620. value_buffer .addr @ c@ [char] " = if
  621. value_buffer .addr @ char+ value_buffer .len @ 2 - strdup
  622. value_buffer .addr @ free if free_error throw then
  623. else
  624. value_buffer .addr @ value_buffer .len @
  625. then
  626. password .len ! password .addr !
  627. 0 value_buffer .addr !
  628. ;
  629. : process_assignment
  630. name_buffer .len @ 0= if exit then
  631. loader_conf_files? if set_conf_files exit then
  632. verbose_flag? if set_verbose exit then
  633. execute? if execute_command exit then
  634. password? if set_password exit then
  635. module_load? if set_module_flag exit then
  636. module_loadname? if set_module_loadname exit then
  637. module_type? if set_module_type exit then
  638. module_args? if set_module_args exit then
  639. module_beforeload? if set_module_beforeload exit then
  640. module_afterload? if set_module_afterload exit then
  641. module_loaderror? if set_module_loaderror exit then
  642. set_environment_variable
  643. ;
  644. \ free_buffer ( -- )
  645. \
  646. \ Free some pointers if needed. The code then tests for errors
  647. \ in freeing, and throws an exception if needed. If a pointer is
  648. \ not allocated, it's value (0) is used as flag.
  649. : free_buffers
  650. line_buffer .addr @ dup if free then
  651. name_buffer .addr @ dup if free then
  652. value_buffer .addr @ dup if free then
  653. or or if free_error throw then
  654. ;
  655. : reset_assignment_buffers
  656. 0 name_buffer .addr !
  657. 0 name_buffer .len !
  658. 0 value_buffer .addr !
  659. 0 value_buffer .len !
  660. ;
  661. \ Higher level file processing
  662. : process_conf
  663. begin
  664. end_of_file? 0=
  665. while
  666. reset_assignment_buffers
  667. read_line
  668. get_assignment
  669. ['] process_assignment catch
  670. ['] free_buffers catch
  671. swap throw throw
  672. repeat
  673. ;
  674. : create_null_terminated_string { addr len -- addr' len }
  675. len char+ allocate if out_of_memory throw then
  676. >r
  677. addr r@ len move
  678. 0 r@ len + c!
  679. r> len
  680. ;
  681. \ Interface to loading conf files
  682. : load_conf ( addr len -- )
  683. 0 to end_of_file?
  684. 0 to read_buffer_ptr
  685. create_null_terminated_string
  686. over >r
  687. fopen fd !
  688. r> free-memory
  689. fd @ -1 = if open_error throw then
  690. ['] process_conf catch
  691. fd @ fclose
  692. throw
  693. ;
  694. : initialize_support
  695. 0 read_buffer .addr !
  696. 0 conf_files .addr !
  697. 0 password .addr !
  698. 0 module_options !
  699. 0 last_module_option !
  700. 0 to verbose?
  701. ;
  702. : print_line
  703. line_buffer .addr @ line_buffer .len @ type cr
  704. ;
  705. : print_syntax_error
  706. line_buffer .addr @ line_buffer .len @ type cr
  707. line_buffer .addr @
  708. begin
  709. line_pointer over <>
  710. while
  711. bl emit
  712. char+
  713. repeat
  714. drop
  715. ." ^" cr
  716. ;
  717. \ Depuration support functions
  718. only forth definitions also support-functions
  719. : test-file
  720. ['] load_conf catch dup .
  721. syntax_error = if cr print_syntax_error then
  722. ;
  723. : show-module-options
  724. module_options @
  725. begin
  726. ?dup
  727. while
  728. ." Name: " dup module.name dup .addr @ swap .len @ type cr
  729. ." Path: " dup module.loadname dup .addr @ swap .len @ type cr
  730. ." Type: " dup module.type dup .addr @ swap .len @ type cr
  731. ." Flags: " dup module.args dup .addr @ swap .len @ type cr
  732. ." Before load: " dup module.beforeload dup .addr @ swap .len @ type cr
  733. ." After load: " dup module.afterload dup .addr @ swap .len @ type cr
  734. ." Error: " dup module.loaderror dup .addr @ swap .len @ type cr
  735. ." Status: " dup module.flag @ if ." Load" else ." Don't load" then cr
  736. module.next @
  737. repeat
  738. ;
  739. only forth also support-functions definitions
  740. \ Variables used for processing multiple conf files
  741. string current_file_name
  742. variable current_conf_files
  743. \ Indicates if any conf file was succesfully read
  744. 0 value any_conf_read?
  745. \ loader_conf_files processing support functions
  746. : set_current_conf_files
  747. conf_files .addr @ current_conf_files !
  748. ;
  749. : get_conf_files
  750. conf_files .addr @ conf_files .len @ strdup
  751. ;
  752. : recurse_on_conf_files?
  753. current_conf_files @ conf_files .addr @ <>
  754. ;
  755. : skip_leading_spaces { addr len pos -- addr len pos' }
  756. begin
  757. pos len = if addr len pos exit then
  758. addr pos + c@ bl =
  759. while
  760. pos char+ to pos
  761. repeat
  762. addr len pos
  763. ;
  764. : get_file_name { addr len pos -- addr len pos' addr' len' || 0 }
  765. pos len = if
  766. addr free abort" Fatal error freeing memory"
  767. 0 exit
  768. then
  769. pos >r
  770. begin
  771. addr pos + c@ bl <>
  772. while
  773. pos char+ to pos
  774. pos len = if
  775. addr len pos addr r@ + pos r> - exit
  776. then
  777. repeat
  778. addr len pos addr r@ + pos r> -
  779. ;
  780. : get_next_file ( addr len ptr -- addr len ptr' addr' len' | 0 )
  781. skip_leading_spaces
  782. get_file_name
  783. ;
  784. : set_current_file_name
  785. over current_file_name .addr !
  786. dup current_file_name .len !
  787. ;
  788. : print_current_file
  789. current_file_name .addr @ current_file_name .len @ type
  790. ;
  791. : process_conf_errors
  792. dup 0= if true to any_conf_read? drop exit then
  793. >r 2drop r>
  794. dup syntax_error = if
  795. ." Warning: syntax error on file " print_current_file cr
  796. print_syntax_error drop exit
  797. then
  798. dup set_error = if
  799. ." Warning: bad definition on file " print_current_file cr
  800. print_line drop exit
  801. then
  802. dup read_error = if
  803. ." Warning: error reading file " print_current_file cr drop exit
  804. then
  805. dup open_error = if
  806. verbose? if ." Warning: unable to open file " print_current_file cr then
  807. drop exit
  808. then
  809. dup free_error = abort" Fatal error freeing memory"
  810. dup out_of_memory = abort" Out of memory"
  811. throw \ Unknown error -- pass ahead
  812. ;
  813. \ Process loader_conf_files recursively
  814. \ Interface to loader_conf_files processing
  815. : include_conf_files
  816. set_current_conf_files
  817. get_conf_files 0
  818. begin
  819. get_next_file ?dup
  820. while
  821. set_current_file_name
  822. ['] load_conf catch
  823. process_conf_errors
  824. recurse_on_conf_files? if recurse then
  825. repeat
  826. ;
  827. \ Module loading functions
  828. : load_module?
  829. module.flag @
  830. ;
  831. : load_parameters ( addr -- addr addrN lenN ... addr1 len1 N )
  832. dup >r
  833. r@ module.args .addr @ r@ module.args .len @
  834. r@ module.loadname .len @ if
  835. r@ module.loadname .addr @ r@ module.loadname .len @
  836. else
  837. r@ module.name .addr @ r@ module.name .len @
  838. then
  839. r@ module.type .len @ if
  840. r@ module.type .addr @ r@ module.type .len @
  841. s" -t "
  842. 4 ( -t type name flags )
  843. else
  844. 2 ( name flags )
  845. then
  846. r> drop
  847. ;
  848. : before_load ( addr -- addr )
  849. dup module.beforeload .len @ if
  850. dup module.beforeload .addr @ over module.beforeload .len @
  851. ['] evaluate catch if before_load_error throw then
  852. then
  853. ;
  854. : after_load ( addr -- addr )
  855. dup module.afterload .len @ if
  856. dup module.afterload .addr @ over module.afterload .len @
  857. ['] evaluate catch if after_load_error throw then
  858. then
  859. ;
  860. : load_error ( addr -- addr )
  861. dup module.loaderror .len @ if
  862. dup module.loaderror .addr @ over module.loaderror .len @
  863. evaluate \ This we do not intercept so it can throw errors
  864. then
  865. ;
  866. : pre_load_message ( addr -- addr )
  867. verbose? if
  868. dup module.name .addr @ over module.name .len @ type
  869. ." ..."
  870. then
  871. ;
  872. : load_error_message verbose? if ." failed!" cr then ;
  873. : load_succesful_message verbose? if ." ok" cr then ;
  874. : load_module
  875. load_parameters load
  876. ;
  877. : process_module ( addr -- addr )
  878. pre_load_message
  879. before_load
  880. begin
  881. ['] load_module catch if
  882. dup module.loaderror .len @ if
  883. load_error \ Command should return a flag!
  884. else
  885. load_error_message true \ Do not retry
  886. then
  887. else
  888. after_load
  889. load_succesful_message true \ Succesful, do not retry
  890. then
  891. until
  892. ;
  893. : process_module_errors ( addr ior -- )
  894. dup before_load_error = if
  895. drop
  896. ." Module "
  897. dup module.name .addr @ over module.name .len @ type
  898. dup module.loadname .len @ if
  899. ." (" dup module.loadname .addr @ over module.loadname .len @ type ." )"
  900. then
  901. cr
  902. ." Error executing "
  903. dup module.beforeload .addr @ over module.afterload .len @ type cr
  904. abort
  905. then
  906. dup after_load_error = if
  907. drop
  908. ." Module "
  909. dup module.name .addr @ over module.name .len @ type
  910. dup module.loadname .len @ if
  911. ." (" dup module.loadname .addr @ over module.loadname .len @ type ." )"
  912. then
  913. cr
  914. ." Error executing "
  915. dup module.afterload .addr @ over module.afterload .len @ type cr
  916. abort
  917. then
  918. throw \ Don't know what it is all about -- pass ahead
  919. ;
  920. \ Module loading interface
  921. : load_modules ( -- ) ( throws: abort & user-defined )
  922. module_options @
  923. begin
  924. ?dup
  925. while
  926. dup load_module? if
  927. ['] process_module catch
  928. process_module_errors
  929. then
  930. module.next @
  931. repeat
  932. ;
  933. \ Additional functions used in "start"
  934. : initialize ( addr len -- )
  935. initialize_support
  936. strdup conf_files .len ! conf_files .addr !
  937. ;
  938. : load_kernel ( -- ) ( throws: abort )
  939. s" load ${kernel} ${kernel_options}" ['] evaluate catch
  940. if s" echo Unable to load kernel: ${kernel_name}" evaluate abort then
  941. ;
  942. : read-password { size | buf len -- }
  943. size allocate if out_of_memory throw then
  944. to buf
  945. 0 to len
  946. begin
  947. key
  948. dup backspace = if
  949. drop
  950. len if
  951. backspace emit bl emit backspace emit
  952. len 1 - to len
  953. else
  954. bell emit
  955. then
  956. else
  957. dup <cr> = if cr drop buf len exit then
  958. [char] * emit
  959. len size < if
  960. buf len chars + c!
  961. else
  962. drop
  963. then
  964. len 1+ to len
  965. then
  966. again
  967. ;
  968. \ Go back to straight forth vocabulary
  969. only forth also definitions