Annotation of qemu/roms/openbios/packages/cmdline.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *   Creation Date: <2003/12/28 14:16:31 samuel>
        !             3:  *   Time-stamp: <2004/01/07 10:37:40 samuel>
        !             4:  *
        !             5:  *     <cmdline.c>
        !             6:  *
        !             7:  *     OpenFirmwware User Interface
        !             8:  *
        !             9:  *   Copyright (C) 2003, 2004 Samuel Rydh ([email protected])
        !            10:  *
        !            11:  *   This program is free software; you can redistribute it and/or
        !            12:  *   modify it under the terms of the GNU General Public License
        !            13:  *   version 2
        !            14:  *
        !            15:  */
        !            16: 
        !            17: #include "config.h"
        !            18: #include "libopenbios/bindings.h"
        !            19: #include "packages.h"
        !            20: #include "libc/vsprintf.h"
        !            21: 
        !            22: typedef struct {
        !            23:        char    *buf;           /* size: ncol+1 */
        !            24:        char    *killbuf;       /* size: ncol+1 */
        !            25:        char    *history;
        !            26:        int     hsize;          /* size of history buffer */
        !            27:        int     ncol;           /* #columns */
        !            28: } cmdline_info_t;
        !            29: 
        !            30: DECLARE_NODE( cmdline, INSTALL_OPEN, sizeof(cmdline_info_t),
        !            31:              "+/packages/cmdline" );
        !            32: 
        !            33: static void
        !            34: emit( int ch )
        !            35: {
        !            36:        PUSH( ch );
        !            37:        fword("emit");
        !            38: }
        !            39: 
        !            40: static int
        !            41: emit_str( const char *str )
        !            42: {
        !            43:        int n = 0;
        !            44:        while( *str ) {
        !            45:                n++;
        !            46:                emit( *str++ );
        !            47:        }
        !            48:        return n;
        !            49: }
        !            50: 
        !            51: static void
        !            52: move_cursor( int n )
        !            53: {
        !            54:        if( n >= 0 ) {
        !            55:                while( n-- )
        !            56:                        emit( '\f' );
        !            57:        } else {
        !            58:                while( n++ )
        !            59:                        emit( 8 );
        !            60:        }
        !            61: }
        !            62: 
        !            63: static void
        !            64: clear( int n )
        !            65: {
        !            66:        int i;
        !            67:        for( i=0; i<n; i++ )
        !            68:                emit(' ');
        !            69:        move_cursor( -n );
        !            70: }
        !            71: 
        !            72: static void
        !            73: clearline( int pos, int n )
        !            74: {
        !            75:        move_cursor( -pos );
        !            76:        clear( n );
        !            77: }
        !            78: 
        !            79: static int
        !            80: key( void )
        !            81: {
        !            82:        fword("key");
        !            83:        return POP();
        !            84: }
        !            85: 
        !            86: /* ( -- flag ) */
        !            87: static void
        !            88: cmdline_open( cmdline_info_t *ci )
        !            89: {
        !            90:        ci->ncol = 80;
        !            91:        ci->buf = malloc( ci->ncol + 1 );
        !            92:        ci->killbuf = malloc( ci->ncol + 1 );
        !            93: 
        !            94:        ci->hsize = 40;
        !            95:        ci->history = malloc( ci->hsize );
        !            96:        ci->history[0] = 0;
        !            97: 
        !            98:        RET( -1 );
        !            99: }
        !           100: 
        !           101: /* ( -- ) */
        !           102: static void
        !           103: cmdline_close( cmdline_info_t *ci )
        !           104: {
        !           105:        free( ci->buf );
        !           106:        free( ci->killbuf );
        !           107:        free( ci->history );
        !           108: }
        !           109: 
        !           110: 
        !           111: static char *
        !           112: history_get( cmdline_info_t *ci, int n )
        !           113: {
        !           114:        char *p = ci->history;
        !           115:        int len;
        !           116: 
        !           117:        while( n-- && p )
        !           118:                if( (p=strchr(p,'\n')) )
        !           119:                        p++;
        !           120: 
        !           121:        ci->buf[0] = 0;
        !           122:        if( !p )
        !           123:                 return NULL;
        !           124: 
        !           125:        for( len=0; len <= ci->ncol && p[len] != '\n' && p[len] ; len++ )
        !           126:                ;
        !           127:        memcpy( ci->buf, p, len );
        !           128:        ci->buf[len] = 0;
        !           129:        return p;
        !           130: }
        !           131: 
        !           132: static int
        !           133: history_remove( cmdline_info_t *ci, int line )
        !           134: {
        !           135:        char *s, *p = history_get( ci, line );
        !           136: 
        !           137:        if( !p || !(s=strchr(p, '\n')) )
        !           138:                return 1;
        !           139:        s++;
        !           140:        memmove( p, s, strlen(s)+1 );
        !           141:        return 0;
        !           142: }
        !           143: 
        !           144: static int /* ( -- ) */
        !           145: add_to_history( cmdline_info_t *ci, char *str )
        !           146: {
        !           147:        int n, len;
        !           148: 
        !           149:        if( !ci->history )
        !           150:                return 0;
        !           151:        len = strlen(str);
        !           152:        if( !len )
        !           153:                return 0;
        !           154: 
        !           155:        /* make room for line in history */
        !           156:        for( ;; ) {
        !           157:                char *p;
        !           158:                n = strlen(ci->history) + 1;
        !           159: 
        !           160:                if( n + len + 1 <= ci->hsize )
        !           161:                        break;
        !           162: 
        !           163:                if( !(p=strrchr(ci->history,'\n')) )
        !           164:                        return 0;
        !           165:                *p = 0;
        !           166:                if( !(p=strrchr(ci->history, '\n')) )
        !           167:                        p = ci->history-1;
        !           168:                p[1] = 0;
        !           169:        }
        !           170: 
        !           171:        memmove( ci->history + len + 1, ci->history, n );
        !           172:        memcpy( ci->history, str, len );
        !           173:        ci->history[ len ] = '\n';
        !           174:        return 1;
        !           175: }
        !           176: 
        !           177: static void /* ( -- ) */
        !           178: cmdline_prompt( cmdline_info_t *ci )
        !           179: {
        !           180:        int cur_added=0, histind=0, ch, i, pos=0, n=0, prompt=1;
        !           181:         char *buf;
        !           182:        int terminate = 0;
        !           183: 
        !           184:        buf = ci->buf;
        !           185:        selfword("prepare");
        !           186: 
        !           187:        emit('\n');
        !           188: #ifdef NOLEAVE
        !           189:        for (;;)
        !           190: #else
        !           191:        while (rstackcnt && !terminate)
        !           192: #endif
        !           193:        {
        !           194:                int drop = 0;
        !           195:                terminate = 0;
        !           196: 
        !           197:                if( prompt ) {
        !           198:                        fword("print-prompt");
        !           199:                        buf[0] = 0;
        !           200:                        cur_added = prompt = histind = pos = n = 0;
        !           201:                }
        !           202: 
        !           203:                ch = key();
        !           204:                switch( ch ) {
        !           205:                case 27:
        !           206:                        switch( key() ) {
        !           207:                        case 'f':
        !           208:                                while( buf[pos] == ' ' )
        !           209:                                        emit( buf[pos++] );
        !           210:                                while( buf[pos] && buf[pos] != ' ' )
        !           211:                                        emit( buf[pos++] );
        !           212:                                break;
        !           213: 
        !           214:                        case 'b':
        !           215:                                while( pos && buf[pos-1] == ' ' ) {
        !           216:                                        move_cursor( -1 );
        !           217:                                        pos--;
        !           218:                                }
        !           219:                                while( pos && buf[pos-1] != ' ' ) {
        !           220:                                        move_cursor( -1 );
        !           221:                                        pos--;
        !           222:                                }
        !           223:                                break;
        !           224:                        case '[':
        !           225:                                switch( key() ) {
        !           226:                                case 'A':
        !           227:                                        goto go_up;
        !           228:                                case 'B':
        !           229:                                        goto go_down;
        !           230:                                case 'C':
        !           231:                                        goto go_right;
        !           232:                                case 'D':
        !           233:                                        goto go_left;
        !           234:                                case '3':
        !           235:                                        key();
        !           236:                                        goto delete;
        !           237:                                }
        !           238:                                break;
        !           239:                        case 'O':
        !           240:                                switch(key()) {
        !           241:                                case 'F':
        !           242:                                        goto go_end;
        !           243:                                case 'H':
        !           244:                                        goto go_home;
        !           245:                                }
        !           246:                                break;
        !           247:                        }
        !           248:                        break;
        !           249:                case '\n':
        !           250:                case '\r':
        !           251:                        if( cur_added )
        !           252:                                history_remove( ci, 0 );
        !           253:                        add_to_history( ci, ci->buf );
        !           254: 
        !           255:                        emit_str( &buf[pos] );
        !           256:                        emit(' ');
        !           257:                        PUSH( feval(buf) );
        !           258:                        fword("print-status");
        !           259: 
        !           260:                        /* Leave the interpreter if terminate? value set */
        !           261:                        fword("terminate?");
        !           262:                        if (POP())
        !           263:                                terminate = 1;
        !           264: 
        !           265:                        prompt = 1;
        !           266:                        break;
        !           267: 
        !           268:                case 3: /* ^c */
        !           269:                        emit_str("\n");
        !           270:                        prompt = 1;
        !           271:                        if( cur_added )
        !           272:                                history_remove( ci, 0 );
        !           273:                        break;
        !           274: 
        !           275:                case 4: /* ^d */
        !           276: delete:
        !           277:                        if( pos == n )
        !           278:                                break;
        !           279:                        emit( buf[pos++] );
        !           280:                        /* fall through */
        !           281: 
        !           282:                case 8: /* ^h */
        !           283:                case 127: /* backspace */
        !           284:                        drop = 1;
        !           285:                        if( !pos )
        !           286:                                break;
        !           287:                        move_cursor( -1 );
        !           288:                        emit_str( &buf[pos] );
        !           289:                        emit(' ');
        !           290:                        memmove( &buf[pos-1], &buf[pos], n+1-pos );
        !           291:                        move_cursor( pos-n-1 );
        !           292:                        pos--;
        !           293:                        n--;
        !           294:                        break;
        !           295: 
        !           296:                case 1: /* ^a */
        !           297: go_home:
        !           298:                        move_cursor( -pos );
        !           299:                        pos = 0;
        !           300:                        break;
        !           301: 
        !           302:                case 5: /* ^e */
        !           303: go_end:
        !           304:                        pos += emit_str( &buf[pos] );
        !           305:                        break;
        !           306: 
        !           307:                //case 68: /* left */
        !           308:                //      drop = 1;
        !           309:                case 2: /* ^b */
        !           310: go_left:
        !           311:                        if( pos ) {
        !           312:                                move_cursor( -1 );
        !           313:                                pos--;
        !           314:                        }
        !           315:                        break;
        !           316: 
        !           317:                //case 67: /* right */
        !           318:                //      drop = 1;
        !           319:                case 6: /* ^f */
        !           320: go_right:
        !           321:                        if( pos < n )
        !           322:                                emit( buf[pos++] );
        !           323:                        break;
        !           324: 
        !           325:                case 11: /* ^k */
        !           326:                        strcpy( ci->killbuf, &buf[pos] );
        !           327:                        clear( n-pos );
        !           328:                        n = pos;
        !           329:                        buf[pos] = 0;
        !           330:                        break;
        !           331: 
        !           332:                case 25: /* ^y */
        !           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++]) );
        !           337:                        }
        !           338:                        break;
        !           339: 
        !           340:                case 9: /* TAB */
        !           341:                        for( i=0; n < ci->ncol && (!i || (pos%4)) ; i++, n++ ) {
        !           342:                                memmove( &buf[pos+1], &buf[pos], n+1-pos );
        !           343:                                buf[pos] = ' ';
        !           344:                                move_cursor( 1-emit_str(&buf[pos++]) );
        !           345:                        }
        !           346:                        break;
        !           347: 
        !           348:                case 12: /* ^l */
        !           349:                        move_cursor( -ci->ncol -pos );
        !           350:                        fword("print-prompt");
        !           351:                        move_cursor( pos-emit_str(buf) );
        !           352:                        break;
        !           353: 
        !           354:                //case 66: /* down */
        !           355:                //      drop = 1;
        !           356:                case 14: /* ^n */
        !           357: go_down:
        !           358:                        if( !histind )
        !           359:                                break;
        !           360:                        history_get( ci, --histind - 1);
        !           361:                        clearline( pos, n );
        !           362:                        emit_str( buf );
        !           363:                        pos = n = strlen( buf );
        !           364:                        if( !histind && cur_added ) {
        !           365:                                cur_added = 0;
        !           366:                                history_remove( ci, 0 );
        !           367:                        }
        !           368:                        break;
        !           369: 
        !           370:                //case 65: /* up */
        !           371:                //      drop = 1;
        !           372:                case 16: /* ^p */
        !           373: go_up:
        !           374:                        if( !histind && add_to_history(ci, ci->buf) ) {
        !           375:                                cur_added = 1;
        !           376:                                histind++;
        !           377:                        }
        !           378:                        if( history_get(ci, histind) )
        !           379:                                histind++;
        !           380:                        clearline( pos, n );
        !           381:                        emit_str( buf );
        !           382:                        pos = n = strlen( buf );
        !           383:                        break;
        !           384:                }
        !           385:                if( (unsigned int)ch < 32 )
        !           386:                        drop = 1;
        !           387: 
        !           388:                if( !drop && n < ci->ncol ) {
        !           389:                        memmove( &buf[pos+1], &buf[pos], n+1-pos );
        !           390:                        n++;
        !           391:                        buf[pos] = ch;
        !           392:                        move_cursor( 1-emit_str(&buf[pos++]) );
        !           393:                }
        !           394:        }
        !           395: 
        !           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 */
        !           399: 
        !           400:        /* Reset stack and terminate? */
        !           401:        rstackcnt = dbgrstackcnt;
        !           402:        feval("0 to terminate?");
        !           403: }
        !           404: 
        !           405: NODE_METHODS( cmdline ) = {
        !           406:        { "open",       cmdline_open      },
        !           407:        { "close",      cmdline_close       },
        !           408:        { "cmdline",     cmdline_prompt      },
        !           409: };
        !           410: 
        !           411: void
        !           412: cmdline_init( void )
        !           413: {
        !           414:        REGISTER_NODE( cmdline );
        !           415: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.