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 );