2 * Creation Date: <2003/12/28 14:16:31 samuel>
3 * Time-stamp: <2004/01/07 10:37:40 samuel>
7 * OpenFirmwware User Interface
9 * Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se)
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
18 #include "libopenbios/bindings.h"
20 #include "libc/vsprintf.h"
23 char *buf
; /* size: ncol+1 */
24 char *killbuf
; /* size: ncol+1 */
26 int hsize
; /* size of history buffer */
27 int ncol
; /* #columns */
30 DECLARE_NODE( cmdline
, INSTALL_OPEN
, sizeof(cmdline_info_t
),
31 "+/packages/cmdline" );
41 emit_str( const char *str
)
73 clearline( int pos
, int n
)
88 cmdline_open( cmdline_info_t
*ci
)
91 ci
->buf
= malloc( ci
->ncol
+ 1 );
92 ci
->killbuf
= malloc( ci
->ncol
+ 1 );
95 ci
->history
= malloc( ci
->hsize
);
103 cmdline_close( cmdline_info_t
*ci
)
112 history_get( cmdline_info_t
*ci
, int n
)
114 char *p
= ci
->history
;
118 if( (p
=strchr(p
,'\n')) )
125 for( len
=0; len
<= ci
->ncol
&& p
[len
] != '\n' && p
[len
] ; len
++ )
127 memcpy( ci
->buf
, p
, len
);
133 history_remove( cmdline_info_t
*ci
, int line
)
135 char *s
, *p
= history_get( ci
, line
);
137 if( !p
|| !(s
=strchr(p
, '\n')) )
140 memmove( p
, s
, strlen(s
)+1 );
144 static int /* ( -- ) */
145 add_to_history( cmdline_info_t
*ci
, char *str
)
155 /* make room for line in history */
158 n
= strlen(ci
->history
) + 1;
160 if( n
+ len
+ 1 <= ci
->hsize
)
163 if( !(p
=strrchr(ci
->history
,'\n')) )
166 if( !(p
=strrchr(ci
->history
, '\n')) )
171 memmove( ci
->history
+ len
+ 1, ci
->history
, n
);
172 memcpy( ci
->history
, str
, len
);
173 ci
->history
[ len
] = '\n';
177 static void /* ( -- ) */
178 cmdline_prompt( cmdline_info_t
*ci
)
180 int cur_added
=0, histind
=0, ch
, i
, pos
=0, n
=0, prompt
=1;
191 while (rstackcnt
&& !terminate
)
198 fword("print-prompt");
200 cur_added
= prompt
= histind
= pos
= n
= 0;
208 while( buf
[pos
] == ' ' )
210 while( buf
[pos
] && buf
[pos
] != ' ' )
215 while( pos
&& buf
[pos
-1] == ' ' ) {
219 while( pos
&& buf
[pos
-1] != ' ' ) {
252 history_remove( ci
, 0 );
253 add_to_history( ci
, ci
->buf
);
255 emit_str( &buf
[pos
] );
258 fword("print-status");
260 /* Leave the interpreter if terminate? value set */
272 history_remove( ci
, 0 );
283 case 127: /* backspace */
288 emit_str( &buf
[pos
] );
290 memmove( &buf
[pos
-1], &buf
[pos
], n
+1-pos
);
291 move_cursor( pos
-n
-1 );
304 pos
+= emit_str( &buf
[pos
] );
307 //case 68: /* left */
317 //case 67: /* right */
326 strcpy( ci
->killbuf
, &buf
[pos
] );
333 for( i
=0; n
< ci
->ncol
&& ci
->killbuf
[i
] ; i
++, n
++ ) {
334 memmove( &buf
[pos
+1], &buf
[pos
], n
+1-pos
);
335 buf
[pos
] = ci
->killbuf
[i
];
336 move_cursor( 1-emit_str(&buf
[pos
++]) );
341 for( i
=0; n
< ci
->ncol
&& (!i
|| (pos
%4)) ; i
++, n
++ ) {
342 memmove( &buf
[pos
+1], &buf
[pos
], n
+1-pos
);
344 move_cursor( 1-emit_str(&buf
[pos
++]) );
349 move_cursor( -ci
->ncol
-pos
);
350 fword("print-prompt");
351 move_cursor( pos
-emit_str(buf
) );
354 //case 66: /* down */
360 history_get( ci
, --histind
- 1);
363 pos
= n
= strlen( buf
);
364 if( !histind
&& cur_added
) {
366 history_remove( ci
, 0 );
374 if( !histind
&& add_to_history(ci
, ci
->buf
) ) {
378 if( history_get(ci
, histind
) )
382 pos
= n
= strlen( buf
);
385 if( (unsigned int)ch
< 32 )
388 if( !drop
&& n
< ci
->ncol
) {
389 memmove( &buf
[pos
+1], &buf
[pos
], n
+1-pos
);
392 move_cursor( 1-emit_str(&buf
[pos
++]) );
396 /* we only get here if terminate? is non-zero; this should
397 * only ever be done for a subordinate forth interpreter
398 * e.g. for debugging */
400 /* Reset stack and terminate? */
401 rstackcnt
= dbgrstackcnt
;
402 feval("0 to terminate?");
405 NODE_METHODS( cmdline
) = {
406 { "open", cmdline_open
},
407 { "close", cmdline_close
},
408 { "cmdline", cmdline_prompt
},
414 REGISTER_NODE( cmdline
);