Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / arch / sun / cmn-msg-format.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: cmn-msg-format.fth
4\
5\ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6\
7\ - Do no alter or remove copyright notices
8\
9\ - Redistribution and use of this software in source and binary forms, with
10\ or without modification, are permitted provided that the following
11\ conditions are met:
12\
13\ - Redistribution of source code must retain the above copyright notice,
14\ this list of conditions and the following disclaimer.
15\
16\ - Redistribution in binary form must reproduce the above copyright notice,
17\ this list of conditions and the following disclaimer in the
18\ documentation and/or other materials provided with the distribution.
19\
20\ Neither the name of Sun Microsystems, Inc. or the names of contributors
21\ may be used to endorse or promote products derived from this software
22\ without specific prior written permission.
23\
24\ This software is provided "AS IS," without a warranty of any kind.
25\ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
26\ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
27\ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
28\ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
29\ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
30\ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
31\ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
32\ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
33\ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
34\ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
35\ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
36\
37\ You acknowledge that this software is not designed, licensed or
38\ intended for use in the design, construction, operation or maintenance of
39\ any nuclear facility.
40\
41\ ========== Copyright Header End ============================================
42id: @(#)cmn-msg-format.fth 1.16 06/06/15 17:20:05
43purpose: Common messaging framework
44copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
45copyright: Use is subject to license terms.
46
47headerless
48
49defer platform-fatal-hook ' noop is platform-fatal-hook
50defer platform-error-hook ' noop is platform-error-hook
51defer platform-warning-hook ' noop is platform-warning-hook
52defer platform-note-hook ' noop is platform-note-hook
53defer platform-cmn-end-hook ' noop is platform-cmn-end-hook
54defer platform-cmn-end-hook2 ' noop is platform-cmn-end-hook2
55
56\ System FATAL and ERROR flags
57\ If you set the fatal state the machine will suppress the boot command
58\ and will not attempt to auto-boot, it will also print an ugly message.
59\ If you set the error-state? an auto-boot? may not happen.
60
610 value system-fatal-state?
620 value system-error-state?
63
64headers vocabulary cmn-messaging
65also cmn-messaging definitions
66headerless
67
68\ Message categories are as follows:
69\ we are converting these numbers into the matching bitpatterns that the
70\ verbosity framework uses so we can use simple AND logic to determine if
71\ the message is printed.
72
73VRBS-MAX VRBS-DEBUG or constant cmn-type
74h# 40 cmn-type or constant cmn-msg
75VRBS-MED cmn-msg or constant cmn-note
76VRBS-MIN cmn-note or constant cmn-warning
77h# 80 cmn-warning or constant cmn-error
78VRBS-NONE cmn-error or constant cmn-fatal
79
80\ Message Frame Data Structure Format
81\ Each message frame contains the following fields:
82\
83\ 8 bytes - address of the parent frame (0 if no parent)
84\ 8 bytes - address of the first child frame (0 if no children)
85\ 8 bytes - address of the next peer frame (0 if no more peers)
86\ 8 bytes - address of the message buffer (allocated dynamically)
87\ 8 bytes - phandle of the device pathname associated with message
88\ 1 byte - category of common message
89\ 1 byte - message completion flag (true/false)
90
91struct
92/n field >cmn-parent \ address of the parent frame
93/n field >cmn-child \ address of the first child frame
94/n field >cmn-peer \ address of the peer frame
95/n field >cmn-message \ address of the message buffer
96/n field >cmn-phandle \ phandle of the device pathname
97/c field >cmn-category \ category of common message
98/c field >cmn-completion \ message completion flag
99constant /cmn-frame
100
101\ Message Data Structure Format
102\ Each message contains the following fields:
103\
104\ 2 bytes - max length of the current string
105\ 2 bytes - length of the current text sting
106\ N bytes - current text sting itself
107
108struct
109/w field >cmn-message>maxlen \ max length of the long string
110/w field >cmn-message>lstr \ start of long counted text string
111constant /cmn-message
112
113\ Size of initial message buffer and size of each increment
114d# 255 constant max-message-len
115
116variable current-frame$ 0 current-frame$ ! \ pointer to the current message frame
117
118\ Long packed strings format: first 2 bytes - count, then string itself.
119\ long-count takes long packed string address from the stack and returns
120\ the string address and the length of the string on the stack.
121
122: long-count ( lpstr -- str,len) dup wa1+ swap w@ ;
123
124\ Concatenates a string to the end of packed long string
125: $long-cat ( adr len lpstr -- )
126 >r r@ long-count ca+ ( adr len end-adr ) ( r: lpstr )
127 swap dup >r ( adr end-adr len ) ( r: lpstr len )
128 cmove r> r> ( len lpstr )
129 dup w@ rot ca+ swap w!
130;
131
132\ Concatenates a given number of spaces to end of packed long string
133: $long-spaces ( n lpstr -- )
134 >r r@ long-count ca+ ( n end-adr ) ( r: lpstr )
135 over bl fill r> ( n lpstr )
136 dup w@ rot ca+ swap w!
137;
138
139\ Returns phandle for active instance or 0 if no instance
140: ?phandle ( -- phandle|0) my-self dup if ihandle>phandle then ;
141
142\ Add a new child to the current frame.
143\ If this is the first child, it becomes the frame's >cmn-child.
144\ Otherwise it becomes the last entry in the >cmn-peer chain starting from >cmn-child.
145
146: add-new-child ( new-frame-addr -- )
147 current-frame$ @ >cmn-child
148 begin
149 dup @
150 while
151 @ >cmn-peer
152 repeat
153 !
154;
155
156: current>message ( -- addr) current-frame$ @ >cmn-message ;
157: current>string ( -- addr) current>message @ >cmn-message>lstr ;
158: current>maxlen ( -- addr) current>message @ >cmn-message>maxlen ;
159
160\ Ensures that current>string is long enough to $long-cat n bytes
161
162: expand-current>string ( n -- )
163
164 \ Calculate length of new string
165 current>string w@ + ( len )
166
167 \ Retrieve the max length of the current message buffer and compare
168 dup current>maxlen w@ > if \ Need allocate bigger message buffer
169
170 \ Calculate the size of the new message frame
171 max-message-len / 1+ max-message-len * ( new-len )
172
173 \ Allocate new message buffer
174 dup /cmn-message + alloc-mem ( new-len new-buffer-addr )
175
176 \ Erase new message buffer header
177 dup /cmn-message erase ( new-len new-buffer-addr )
178
179 \ Move old message to the new bigger buffer
180 dup >cmn-message>lstr current>string long-count rot $long-cat ( new-len new-buffer-addr )
181
182 \ Update new buffer maxlen field
183 tuck >cmn-message>maxlen w! ( new-buffer-addr )
184
185 \ Release old message buffer
186 current>message @ ( new-buffer-addr old-buffer-addr )
187 current>maxlen w@ ( new-buffer-addr old-buffer-addr old-len )
188 /cmn-message + free-mem ( new-buffer-addr )
189
190 \ Update message frame >cmn-message pointer
191 current>message ! ( )
192
193 else ( len )
194 drop ( )
195 then ( )
196;
197
198\ Like "type", but buffered into current message frame
199: buffered-type ( adr,len -- )
200 dup expand-current>string ( adr,len )
201 current>string $long-cat ( )
202;
203
204\ Like "spaces", but buffered into current message frame
205: buffered-spaces ( n -- )
206 dup expand-current>string ( adr,len )
207 current>string $long-spaces
208;
209
210\ There is one [ifdef] in this file: [ifdef] cmn-reentrant?
211\ this is a place holder so that the entire cmn-append code becomes
212\ re-entrant.
213\
214\ FWARC/2004/311 format encoder extension
215\
216\ This works by parsing the string from left->right, recursing until all the
217\ tokens are encoded, and then pushing the stack items into the fmt-data
218\ structures on the return (unnesting) path.
219\
220\ Once the sequence is complete the stack is logically empty and the entire
221\ sequence is replayed left-to-right.
222\
223\ Each fmt-data structure will contain the acf of the number->string encoder
224\ appropriate for the encoding and the actual stack data.
225\ After each node is processed the node is released.
226\
227\ Everything ends up being funnelled through the (fmt-s) routine, so buffering
228\ the constructed message should be trivial - though it will be assembled in
229\ pieces.
230\
231\ How to use this:
232\
233\ 1) man printf and read, this covers the basics.
234\ 2) the delta with printf is the % behaviour; printf will consume
235\ the %<illegal> and this implemention does not.
236\ If you want to print a %x (a reserved sequence) you need to
237\ escape the % by using another one. %%x
238\
239\ Valid encodings are:
240\
241\ %c - character
242\ %d - signed decimal 32bit value
243\ %x - unsigned hex 32bit value
244\ %ld - signed decimal 64bit value
245\ %lx - unsigned hex 64bit value
246\
247\ In addition you can encode field widths for all the valid encodings.
248\
249\ An example using decimal.
250\
251\ %5d - put a 32bit signed decimal number in
252\ a field width of 5, the number is truncated
253\ and right justified.
254\ %-5d - put a 32bit signed decimal number in
255\ a field width of 5, the number is truncated
256\ and left justified.
257\
258\ A simple example, print a name and an age and a newline.
259\
260\ : display-record ( name$ age -- )
261\ cmn-type[ " %s is %d years old"r"n" ]cmn-end
262\ ;
263\
264\ Note that the arguments are used in the order they appear in the stack
265\ diagram - from left to right, NOT by their stack positions.
266\
267\ Extending the example a little, to put the name and age in fixed width
268\ fields: 10 characters for the name, left justified and 3 for the age.
269\
270\ : display-record ( name$ age -- )
271\ cmn-type[ " %-10s is %3d years old"r"n" ]cmn-end
272\ ;
273
274variable fmt-head
275variable fmt-tail
276struct
277 /n field >fmt-next \ next format block
278 /c field >fmt-width \ field width
279 /c field >fmt-flags \ bit0 = Long Value, bit1 = unsigned
280 /w field >fmt-data
281 /n field >fmt-encode \ type encoder
282 2 /n* field >fmt-args \ data for encoder
283constant /fmt-data
284
285\ ff is -1.
286\ a primitive sign extending c@ would be nice - like <w@
287
288[ifnexist] <c@
289: <c@ ( n -- x ) c@ dup h# 80 and if d# 256 - then ;
290[then]
291
292\ copy the args out
293: (fmt-s) ( ptr -- )
294 >r r@ >fmt-args 2@ ( str len )
295 r> >fmt-width <c@ ( str len )
296 ?dup if
297 >r r@ 0< if ( str,len )
298 r@ abs min ( str,len' )
299 tuck buffered-type ( len' )
300 r> + ( n )
301 negate buffered-spaces exit ( )
302 else ( str,len )
303 r@ min ( str,len )
304 r> over - buffered-spaces ( )
305 then
306 then
307 buffered-type
308;
309
310: (fmt-cpy) ( ptr -- ) >fmt-args 2@ buffered-type ;
311: (fmt-c) ( ptr -- )
312 >r
313 r@ >fmt-args @ r@ >fmt-data c!
314 r@ >fmt-data 1 r@ >fmt-args 2!
315 r> (fmt-s)
316;
317: (fmt-.n) ( ptr -- )
318 >r r@ >fmt-args dup @ ( dptr data )
319 r@ >fmt-flags c@ case ( dptr data )
320 0 of over l! dup <l@ (.) endof \ signed 32 bit
321 1 of (.) endof \ 64 bit, signed
322 2 of over l! dup l@ (u.) endof \ unsigned 32 bit
323 3 of (u.) endof \ 64 bit, unsigned
324 endcase
325 rot 2! ( )
326 r> (fmt-s) ( )
327;
328
329: (fmt-.d) ( ptr -- ) decimal (fmt-.n) ;
330: (fmt-.x) ( ptr -- ) hex (fmt-.n) ;
331
332: (fmt-save) ( ?? items ptr -- )
333 >r case ( ?? )
334 0 of endof ( )
335 1 of r@ >fmt-args ! endof ( )
336 2 of r@ >fmt-args 2! endof ( )
337 ." Can't support " .d ." arguments in common messaging string" cr
338 abort
339 endcase ( )
340 r> drop ( )
341;
342
343: (fmt-push) ( ?? items code acf -- node )
344 /fmt-data alloc-mem >r ( )
345 r@ >fmt-encode ! ( ?? items code )
346 wbsplit ( ?? items width flags )
347 r@ >fmt-flags c! ( ?? items width )
348 r@ >fmt-width c! ( ?? items )
349 0 r@ >fmt-next ! ( ?? items )
350 r@ (fmt-save) ( )
351 r@ ( node )
352 fmt-tail dup @ ( node ptr tail )
353 r@ ( node ptr tail node )
354 rot ! ( node tail )
355 ?dup if ( node tail )
356 >fmt-next ! ( )
357 else ( node )
358 fmt-head ! ( )
359 then ( )
360 r> ( node )
361;
362
363\ Unroll the string
364: (fmt-exec) ( -- )
365 fmt-head @ ( ptr )
366 begin ( ptr )
367 ?dup while ( ptr )
368 >r r@ r@ >fmt-encode @ execute ( ptr )
369 r@ >fmt-next @ ( ptr )
370 r> /fmt-data free-mem ( ptr )
371 dup fmt-head ! ( ptr )
372 repeat ( )
373;
374
375: (fmt-valid?) ( ptr -- flag )
376 c@ case
377 ascii d of true endof \ decimal
378 ascii x of true endof \ hex
379 ascii c of true endof \ char
380 ascii s of true endof \ string
381 ascii p of true endof \ pointer
382 false swap
383 endcase
384;
385
386\ verify that the string contains a valid encoder sequence.
387\ return the skip size (2 for ld), (1 for d) for example.
388\ and a flag.
389
390: (sfmt-valid?) ( str,len -- str,len,n,-1 | str,len,0 )
391 dup 2 >= if ( str,len )
392 over c@ ascii l = if ( str,len )
393 over 1+ (fmt-valid?) if ( str,len )
394 2 true ( str,len )
395 else ( str,len )
396 false ( str,len,0 )
397 then ( str,len )
398 exit ( str,len,n,-1 | str,len,0 )
399 then ( str,len )
400 then ( str,len )
401 over (fmt-valid?) if ( str,len )
402 1 true ( str,len,1,true )
403 else ( str,len )
404 false ( str,len,0 )
405 then ( str,len,n,-1 | str,len,0 )
406;
407
408\ an optimisation for tokens..
409: ((fmt-.x)) h# 200 or ['] (fmt-.x) 1 false ;
410
411\ convert the character encoding into field widths, and the encoder
412\ acf
413: (fmt-decode) ( flags,ptr -- flags,acf,n,flag )
414 c@ case
415 ascii d of ['] (fmt-.d) 1 false endof \ decimal
416 ascii x of ((fmt-.x)) endof \ hex (unsigned)
417 ascii c of ['] (fmt-c) 1 false endof \ char
418 ascii s of ['] (fmt-s) 2 false endof \ string
419 ascii p of ((fmt-.x)) endof \ hex pointer
420 >r 2 ['] (fmt-cpy) true r>
421 endcase
422;
423
424\ return true if this string does not have a valid encoding
425\ else return false, the field with and the encoding acf
426
427: (scan-for-fmt) ( str$ -- str$,w,acf,n,0 | str$,true )
428 recursive
429 over c@ ascii % = if ( str$ )
430 \ %% forces a % which is a special case
431 1 /string true ( str$,true )
432 exit ( str$,true )
433 then ( str$ )
434
435 \ Simple fieldless sequence?
436 (sfmt-valid?) if ( str$,n )
437 2 pick >r ( str$,n )
438 >r r@ /string ( str$' )
439 0 r@ 1- bwjoin ( str$,w )
440 r> 1- r> + (fmt-decode) ( str$,w,acf,n,flag )
441 exit ( str,len )
442 then ( str,len )
443
444 \ field is left justified?
445 over c@ ascii - = if ( str,len 1 )
446 -1 1 ( str,len -1 1 )
447 else ( str,len )
448 0 0 ( str,len 1 0 )
449 then ( str,len 1 0 )
450
451 \ skip the numbers
452 3 pick + 0 ( str,len sign num,len )
453 begin ( str,len sign num,len )
454 2dup + c@ d# 10 digit nip while ( str,len sign num,n )
455 1+ ( str,len sign )
456 repeat ( str,len sign num,len )
457
458 \ verify the token following the numbers (if any)
459 ?dup if ( str,len sign num,len )
460 rot /string ( str,len num,len )
461 tuck ( str,len len num,len )
462 $number if ( str,len len )
463 drop true exit ( str,len,true )
464 then ( str,len len w )
465 >r ( str,len len )
466 dup ( str,len len len )
467 3 pick + r> over >r >r ( str,len len fmt )
468 2 pick 2 pick - ( str,len len fmt,len )
469 (sfmt-valid?) if ( str,len len fmt,len s )
470 >r 2drop ( str,len len )
471 r@ + /string ( str$ )
472 r> 1- ( str$ s' )
473 r> over bwjoin ( str$ s' code )
474 swap r> + ( str$ code fmt' )
475 (fmt-decode) ( str$ code,acf,n,flag )
476 exit
477 else ( str,len len fmt,len )
478 2r> 3drop ( str,len len fmt )
479 then ( str,len len fmt )
480 then ( str,len len fmt )
481 2drop ( str,len )
482 true ( str$,true )
483;
484
485\ the meat of the parsing
486: (fmt-parse) ( str,len -- )
487 dup 0= if 2drop exit then
488 recursive
489 ascii % left-parse-string ?dup if ( right$ left$ )
490 2 0 ['] (fmt-cpy) (fmt-push) drop ( right$ )
491 else ( right$ leftva )
492 drop ( right$ )
493 then ( right$ )
494 ?dup if ( right$ )
495 (scan-for-fmt) if ( right$ )
496 \ we have a % to print, fake it with a %c conversion
497 ascii % 1 0 ['] (fmt-c) (fmt-push) drop ( right$ )
498 (fmt-parse) ( )
499 else ( right$ )
500 >r 0 -rot (fmt-push) ( right$ ptr )
501 >r (fmt-parse) ( right$ )
502 r> r> swap (fmt-save) ( )
503 then
504 else ( va )
505 drop ( )
506 then ( )
507;
508
509previous definitions also cmn-messaging
510
511headers
512: cmn-append ( ?? str,len -- )
513 \ Check if there is a current frame to append to
514 current-frame$ @ 0= if
515 ??cr
516 ." Missing cmn-xxx[ caused cmn-append with '" type
517 ." ' argument to fail"r"n"
518 abort
519 then
520 [ifdef] cmn-reentrant?
521 fmt-head dup @ >r off fmt-tail dup @ >r off
522 [else]
523 fmt-head off fmt-tail off
524 [then]
525 push-decimal
526 (fmt-parse)
527 (fmt-exec)
528 pop-base
529 [ifdef] cmn-reentrant? r> fmt-tail ! r> fmt-head ! [then]
530;
531
532previous also cmn-messaging definitions
533
534headerless
535: cmn-[ ( msg-category -- )
536
537 \ Allocate buffer for a new message text string
538 max-message-len /cmn-message + alloc-mem ( category message-addr)
539
540 \ Clear the buffer headers with zeroes
541 dup /cmn-message erase ( category message-addr)
542
543 \ Compile buffer length at the beginning into cmn>messsage>maxlen field
544 max-message-len over >cmn-message>maxlen w! ( category message-addr)
545
546 \ Allocate pointer data structure for a new message frame
547 /cmn-frame alloc-mem >r ( category message-addr ) ( r: frame-addr)
548
549 \ Clear the pointer data structure with zeroes
550 r@ /cmn-frame erase ( category message-addr )
551
552 \ Set >cmn-message field;
553 \ Store the pointer to the message text string buffer into >cmn-message field
554 \ of the message frame pointer data structure
555 r@ >cmn-message ! ( category )
556
557 \ Compile the current message category into >cmn-category field
558 \ of the message frame pointer data structure
559 r@ >cmn-category c! ( )
560
561 \ Set >cmn-phandle field
562 \ Store phandle into current >cmn-phandle field
563 \ of the message frame pointer data structure
564 ?phandle r@ >cmn-phandle ! ( )
565
566 \ Set >cmn-parent field
567 \ Store the pointer to the parent frame into >cmn-parent field
568 \ of the message frame pointer data structure
569 current-frame$ @ r@ >cmn-parent !
570
571 \ Set >cmn-peer field
572 0 r@ >cmn-peer !
573 current-frame$ @ if r@ add-new-child then
574
575 \ Store the pointer to the current message frame pointer
576 \ data structure into current-frame$
577 r> current-frame$ ! ( ) ( r: )
578
579 \ The 'lose' is patched to cmn-end, later in this file
580 \ we dont want or need to use a defer!!
581 push-checkpt ?dup if
582 " ...(text may have been truncated due to an exception)"r"n" lose
583 throw
584 then
585
586;
587
588\ Prints the content of the message between cmn-xxx[ and ]cmn-end
589: .message-content ( frame-addr -- )
590 >cmn-message @ >cmn-message>lstr long-count type
591;
592
593\ Prints device path followed by colon
594: .devpath ( frame-addr -- )
595 >cmn-phandle @ ?dup if ( phandle)
596 phandle>devname type
597 ascii : emit space
598 then
599;
600
601\ Selects individual format based on message category
602: (print-message) ( frame-addr -- )
603 >r
604
605 r@ >cmn-category c@ case
606
607 cmn-fatal of
608 ??cr
609 ." FATAL: "
610 r@ .devpath
611 r@ .message-content
612 endof
613
614 cmn-error of
615 ??cr
616 ." ERROR: "
617 r@ .devpath
618 r@ .message-content
619 endof
620
621 cmn-warning of
622 ??cr
623 ." WARNING: "
624 r@ .devpath
625 r@ .message-content
626 endof
627
628 cmn-note of
629 ??cr
630 ." NOTICE: "
631 r@ .message-content
632 endof
633
634 cmn-type of
635 r@ .message-content
636 endof
637
638 cmn-msg of
639 r@ .devpath
640 r@ .message-content
641 endof
642
643 endcase
644
645 r> drop
646;
647
648\ Release messaging frame and message buffer after message was printed
649
650: release-frame ( frame-addr -- )
651
652 \ Release message buffer first
653 dup >cmn-message @ ( frame-addr message-addr)
654 dup >cmn-message>maxlen w@ /cmn-message + ( frame-addr message-addr message-maxlen )
655 free-mem ( frame-addr)
656
657 \ Then release message frame
658 /cmn-frame free-mem ( )
659;
660
661\ Print message based on type and verbosity level
662
663: print-message ( frame -- )
664 fw-verbosity diagnostic-mode? or over >cmn-category c@ and if (print-message) else drop then
665;
666
667\ Common messaging frame printing code
668
669: print-messaging-tree ( frame-addr -- ) recursive
670 begin ?dup while ( frame-addr )
671 dup print-message ( frame-addr )
672 dup >cmn-child @ ( frame-addr child-addr)
673 print-messaging-tree ( frame-addr)
674 dup >cmn-peer @ ( frame-addr peer-addr)
675 swap release-frame ( peer-addr)
676 repeat ( )
677;
678
679\ ]cmn-end should always fetch address from current >cmn-parent
680\ field and store it into current-frame$
681
682: cmn-end ( str,len -- )
683 cmn-append ( )
684 true current-frame$ @ >cmn-completion c! \ Message completed
685 current-frame$ dup @ ( current-frame$ current-frame-addr )
686 >cmn-parent @ ( current-frame$ parent-frame-addr )
687 ?dup if ( current-frame$ parent-frame-addr )
688 swap ! exit ( )
689 then ( current-frame$ )
690 dup @ ( current-frame$ root-frame-addr )
691 platform-cmn-end-hook ( current-frame$ )
692 print-messaging-tree ( current-frame$ )
693 0 swap ! ( )
694 platform-cmn-end-hook2 ( )
695;
696\ Fixup the forward reference in cmn-[
697patch cmn-end lose cmn-[
698
699
700previous definitions also cmn-messaging
701headers
702
703: ]cmn-end ( str,len -- ) cmn-append " "r"n" cmn-end pop-checkpt ;
704
705: cmn-fatal[ ( -- ) platform-fatal-hook true is system-fatal-state? cmn-fatal cmn-[ ;
706: cmn-error[ ( -- ) platform-error-hook true is system-error-state? cmn-error cmn-[ ;
707: cmn-warn[ ( -- ) platform-warning-hook cmn-warning cmn-[ ;
708: cmn-note[ ( -- ) platform-note-hook cmn-note cmn-[ ;
709: cmn-msg[ ( -- ) cmn-msg cmn-[ ;
710: cmn-type[ ( -- ) cmn-type cmn-[ ;
711
712headerless
713\ Close and print all messaging frames currently opened
714: flush-cmn-messages ( -- )
715 begin current-frame$ @ while " " ]cmn-end repeat
716;
717
718headers
719\ Need name here because it is now calling cmn-append
720
721previous definitions
722
723also magic-properties definitions
724
725\ Name now automatically cmn-appends the name of the node
726\ to the current cmn-messaging frame which must be started
727\ with cmn-msg[. Used for OBP probing output. Executes type
728\ if there is no active messaging frame.
729
730: name ( value-str name-str -- value-str name-str )
731 [ also cmn-messaging ]
732 diagnostic-mode? if
733 2over decode-string current-frame$ @ if
734 " %s " cmn-append
735 else
736 type space
737 then
738 2drop
739 then
740 [ previous ]
741;
742
743previous definitions
744
745headerless