Annotation of sbbs/sbbs3/getstr.cpp, revision 1.1.1.1

1.1       root        1: /* getstr.cpp */
                      2: 
                      3: /* Synchronet string input routines */
                      4: 
                      5: /* $Id: getstr.cpp,v 1.3 2000/11/14 02:16:57 rswindell Exp $ */
                      6: 
                      7: /****************************************************************************
                      8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
                      9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
                     10:  *                                                                                                                                                     *
                     11:  * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html         *
                     12:  *                                                                                                                                                     *
                     13:  * This program is free software; you can redistribute it and/or                       *
                     14:  * modify it under the terms of the GNU General Public License                         *
                     15:  * as published by the Free Software Foundation; either version 2                      *
                     16:  * of the License, or (at your option) any later version.                                      *
                     17:  * See the GNU General Public License for more details: gpl.txt or                     *
                     18:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
                     19:  *                                                                                                                                                     *
                     20:  * Anonymous FTP access to the most recent released source is available at     *
                     21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
                     22:  *                                                                                                                                                     *
                     23:  * Anonymous CVS access to the development source and modification history     *
                     24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
                     25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
                     26:  *     (just hit return, no password is necessary)                                                     *
                     27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
                     28:  *                                                                                                                                                     *
                     29:  * For Synchronet coding style and modification guidelines, see                                *
                     30:  * http://www.synchro.net/source.html                                                                          *
                     31:  *                                                                                                                                                     *
                     32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
                     33:  * format) via e-mail to [email protected]                                                                      *
                     34:  *                                                                                                                                                     *
                     35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
                     36:  ****************************************************************************/
                     37: 
                     38: #include "sbbs.h"
                     39: 
                     40: /****************************************************************************/
                     41: /* Waits for remote or local user to input a CR terminated string. 'length' */
                     42: /* is the maximum number of characters that getstr will allow the user to   */
                     43: /* input into the string. 'mode' specifies upper case characters are echoed */
                     44: /* or wordwrap or if in message input (^A sequences allowed). ^W backspaces */
                     45: /* a word, ^X backspaces a line, ^Gs, BSs, TABs are processed, LFs ignored. */
                     46: /* ^N non-destructive BS, ^V center line. Valid keys are echoed.            */
                     47: /****************************************************************************/
                     48: size_t sbbs_t::getstr(char *strout, size_t maxlen, long mode)
                     49: {
                     50:     size_t     i,l,x,z;    /* i=current position, l=length, j=printed chars */
                     51:                     /* x&z=misc */
                     52:        char    str1[256],str2[256];
                     53:     uchar      ch;
                     54:        uchar   ins=0,atr;
                     55: 
                     56:        console&=~CON_UPARROW;
                     57:        sys_status&=~SS_ABORT;
                     58:        if(mode&K_LINE && useron.misc&ANSI && !(mode&K_NOECHO)) {
                     59:                attr(cfg.color[clr_inputline]);
                     60:                for(i=0;i<maxlen;i++)
                     61:                        outchar(SP);
                     62:                bprintf("\x1b[%dD",maxlen); }
                     63:        if(wordwrap[0]) {
                     64:                strcpy(str1,wordwrap);
                     65:                wordwrap[0]=0; }
                     66:        else str1[0]=0;
                     67:        if(mode&K_EDIT)
                     68:                strcat(str1,strout);
                     69:        else
                     70:                strout[0]=0;
                     71:        if(strlen(str1)>maxlen)
                     72:                str1[maxlen]=0;
                     73:        atr=curatr;
                     74:        if(!(mode&K_NOECHO)) {
                     75:                if(mode&K_AUTODEL && str1[0]) {
                     76:                        i=(cfg.color[clr_inputline]&0x77)<<4;
                     77:                        i|=(cfg.color[clr_inputline]&0x77)>>4;
                     78:                        attr(i); }
                     79:                rputs(str1);
                     80:                if(mode&K_EDIT && !(mode&(K_LINE|K_AUTODEL)) && useron.misc&ANSI)
                     81:                        bputs("\x1b[K");  /* destroy to eol */ }
                     82: 
                     83:        i=l=strlen(str1);
                     84:        if(mode&K_AUTODEL && str1[0] && !(mode&K_NOECHO)) {
                     85:                ch=getkey(mode|K_GETSTR);
                     86:                attr(atr);
                     87:                if(isprint(ch) || ch==DEL) {
                     88:                        for(i=0;i<l;i++)
                     89:                                bputs("\b \b");
                     90:                        i=l=0; }
                     91:                else {
                     92:                        for(i=0;i<l;i++)
                     93:                                outchar(BS);
                     94:                        rputs(str1);
                     95:                        i=l; }
                     96:                if(ch!=SP && ch!=TAB)
                     97:                        ungetkey(ch); }
                     98: 
                     99:        while(!(sys_status&SS_ABORT) && (ch=getkey(mode|K_GETSTR))!=CR && online) {
                    100:                if(sys_status&SS_ABORT)
                    101:                        break;
                    102:                if(ch==LF && mode&K_MSG) /* Down-arrow same as CR */
                    103:                        break;
                    104:                if(ch==TAB && (mode&K_TAB || !(mode&K_WRAP)))   /* TAB same as CR */
                    105:                        break;
                    106:                if(!i && mode&K_UPRLWR && (ch==SP || ch==TAB))
                    107:                        continue;       /* ignore beginning white space if upper/lower */
                    108:                if(mode&K_E71DETECT && (uchar)ch==(CR|0x80) && l>1) {
                    109:                        if(strstr(str1,"��")) {
                    110:                                bputs("\r\n\r\nYou must set your terminal to NO PARITY, "
                    111:                                        "8 DATA BITS, and 1 STOP BIT (N-8-1).\7\r\n");
                    112:                                return(0); } }
                    113:                switch(ch) {
                    114:                        case 1: /* Ctrl-A for ANSI */
                    115:                                if(!(mode&K_MSG) || useron.rest&FLAG('A') || i>maxlen-3)
                    116:                                        break;
                    117:                                if(ins) {
                    118:                                        if(l<maxlen)
                    119:                                                l++;
                    120:                                        for(x=l;x>i;x--)
                    121:                                                str1[x]=str1[x-1];
                    122:                                        rprintf("%.*s",l-i,str1+i);
                    123:                                        rprintf("\x1b[%dD",l-i);
                    124:                                        if(i==maxlen-1)
                    125:                                                ins=0; }
                    126:                                outchar(str1[i++]=1);
                    127:                                break;
                    128:                        case 2: /* Ctrl-B Beginning of Line */
                    129:                                if(useron.misc&ANSI && i && !(mode&K_NOECHO)) {
                    130:                                        bprintf("\x1b[%dD",i);
                    131:                                        i=0; }
                    132:                                break;
                    133:                        case 4: /* Ctrl-D Delete word right */
                    134:                                if(i<l) {
                    135:                                        x=i;
                    136:                                        while(x<l && str1[x]!=SP) {
                    137:                                                outchar(SP);
                    138:                                                x++; }
                    139:                                        while(x<l && str1[x]==SP) {
                    140:                                                outchar(SP);
                    141:                                                x++; }
                    142:                                        bprintf("\x1b[%dD",x-i);   /* move cursor back */
                    143:                                        z=i;
                    144:                                        while(z<l-(x-i))  {             /* move chars in string */
                    145:                                                outchar(str1[z]=str1[z+(x-i)]);
                    146:                                                z++; }
                    147:                                        while(z<l) {                    /* write over extra chars */
                    148:                                                outchar(SP);
                    149:                                                z++; }
                    150:                                        bprintf("\x1b[%dD",z-i);
                    151:                                        l-=x-i; }                       /* l=new length */
                    152:                                break;
                    153:                        case 5: /* Ctrl-E End of line */
                    154:                                if(useron.misc&ANSI && i<l) {
                    155:                                        bprintf("\x1b[%dC",l-i);  /* move cursor to eol */
                    156:                                        i=l; }
                    157:                                break;
                    158:                        case 6: /* Ctrl-F move cursor forewards */
                    159:                                if(i<l && (useron.misc&ANSI)) {
                    160:                                        bputs("\x1b[C");   /* move cursor right one */
                    161:                                        i++; }
                    162:                                break;
                    163:                        case 7: /* Ctrl-G */
                    164:                                if(!(mode&K_MSG))
                    165:                                        break;
                    166:                                if(useron.rest&FLAG('B')) {
                    167:                                        if (i+6<maxlen) {
                    168:                                                if(ins) {
                    169:                                                        for(x=l+6;x>i;x--)
                    170:                                                                str1[x]=str1[x-6];
                    171:                                                        if(l+5<maxlen)
                    172:                                                                l+=6;
                    173:                                                        if(i==maxlen-1)
                    174:                                                                ins=0; }
                    175:                                                str1[i++]='(';
                    176:                                                str1[i++]='b';
                    177:                                                str1[i++]='e';
                    178:                                                str1[i++]='e';
                    179:                                                str1[i++]='p';
                    180:                                                str1[i++]=')';
                    181:                                                if(!(mode&K_NOECHO))
                    182:                                                        bputs("(beep)"); }
                    183:                                        if(ins)
                    184:                                                redrwstr(str1,i,l,0);
                    185:                                        break; }
                    186:                                 if(ins) {
                    187:                                        if(l<maxlen)
                    188:                                                l++;
                    189:                                        for(x=l;x>i;x--)
                    190:                                                str1[x]=str1[x-1];
                    191:                                        if(i==maxlen-1)
                    192:                                                ins=0; }
                    193:                                 if(i<maxlen) {
                    194:                                        str1[i++]=BEL;
                    195:                                        if(!(mode&K_NOECHO))
                    196:                                                outchar(BEL); }
                    197:                                 break;
                    198:                        case 8: /* Ctrl-H/Backspace */
                    199:                                if(!i)
                    200:                                        break;
                    201:                                i--;
                    202:                                l--;
                    203:                                if(i!=l) {              /* Deleting char in middle of line */
                    204:                                        outchar(BS);
                    205:                                        z=i;
                    206:                                        while(z<l)  {       /* move the characters in the line */
                    207:                                                outchar(str1[z]=str1[z+1]);
                    208:                                                z++; }
                    209:                                        outchar(SP);        /* write over the last char */
                    210:                                        bprintf("\x1b[%dD",(l-i)+1); }
                    211:                                else if(!(mode&K_NOECHO))
                    212:                                        bputs("\b \b");
                    213:                                break;
                    214:                        case 9: /* Ctrl-I/TAB */
                    215:                                if(!(i%TABSIZE)) {
                    216:                                        if(ins) {
                    217:                                                if(l<maxlen)
                    218:                                                        l++;
                    219:                                                for(x=l;x>i;x--)
                    220:                                                        str1[x]=str1[x-1];
                    221:                                                if(i==maxlen-1)
                    222:                                                        ins=0; }
                    223:                                        str1[i++]=SP;
                    224:                                        if(!(mode&K_NOECHO))
                    225:                                                outchar(SP); }
                    226:                                while(i<maxlen && i%TABSIZE) {
                    227:                                        if(ins) {
                    228:                                                if(l<maxlen)
                    229:                                                        l++;
                    230:                                                for(x=l;x>i;x--)
                    231:                                                        str1[x]=str1[x-1];
                    232:                                                if(i==maxlen-1)
                    233:                                                        ins=0; }
                    234:                                        str1[i++]=SP;
                    235:                                        if(!(mode&K_NOECHO))
                    236:                                                outchar(SP); }
                    237:                                if(ins && !(mode&K_NOECHO))
                    238:                                        redrwstr(str1,i,l,0);
                    239:                                break;
                    240: 
                    241:                        case 12:    /* Ctrl-L   Center line (used to be Ctrl-V) */
                    242:                                str1[l]=0;
                    243:                                l=bstrlen(str1);
                    244:                                if(!l) break;
                    245:                                for(x=0;x<(maxlen-l)/2;x++)
                    246:                                        str2[x]=SP;
                    247:                                str2[x]=0;
                    248:                                strcat(str2,str1);
                    249:                                strcpy(strout,str2);
                    250:                                l=strlen(strout);
                    251:                                if(mode&K_NOECHO)
                    252:                                        return(l);
                    253:                                if(mode&K_MSG)
                    254:                                        redrwstr(strout,i,l,K_MSG);
                    255:                                else {
                    256:                                        while(i--)
                    257:                                                bputs("\b");
                    258:                                        bputs(strout);
                    259:                                        if(mode&K_LINE)
                    260:                                                attr(LIGHTGRAY); }
                    261:                                CRLF;
                    262:                                return(l);
                    263: 
                    264:                        case 14:    /* Ctrl-N Next word */
                    265:                                if(i<l && (useron.misc&ANSI)) {
                    266:                                        x=i;
                    267:                                        while(str1[i]!=SP && i<l)
                    268:                                                i++;
                    269:                                        while(str1[i]==SP && i<l)
                    270:                                                i++;
                    271:                                        bprintf("\x1b[%dC",i-x); }
                    272:                                break;
                    273:                        case 18:    /* Ctrl-R Redraw Line */
                    274:                                if(!(mode&K_NOECHO))
                    275:                                        redrwstr(str1,i,l,0);
                    276:                                break;
                    277:                        case 22:        /* Ctrl-V                       Toggles Insert/Overwrite */
                    278:                                if(!(useron.misc&ANSI) || mode&K_NOECHO)
                    279:                                        break;
                    280:                                if(ins) {
                    281:                                        ins=0;
                    282:                                        redrwstr(str1,i,l,0); }
                    283:                                else if(i<l) {
                    284:                                        ins=1;
                    285:                                        bprintf("\x1b[s\x1b[79C");      /* save pos  */
                    286:                                        z=curatr;                       /* and go to EOL */
                    287:                                        attr(z|BLINK|HIGH);
                    288:                                        outchar('�');
                    289:                                        attr(z);
                    290:                                        bputs("\x1b[u"); }  /* restore pos */
                    291:                                break;
                    292:                        case 23:    /* Ctrl-W   Delete word left */
                    293:                                if(i<l) {
                    294:                                        x=i;                            /* x=original offset */
                    295:                                        while(i && str1[i-1]==SP) {
                    296:                                                outchar(BS);
                    297:                                                i--; }
                    298:                                        while(i && str1[i-1]!=SP) {
                    299:                                                outchar(BS);
                    300:                                                i--; }
                    301:                                        z=i;                            /* i=z=new offset */
                    302:                                        while(z<l-(x-i))  {             /* move chars in string */
                    303:                                                outchar(str1[z]=str1[z+(x-i)]);
                    304:                                                z++; }
                    305:                                        while(z<l) {                    /* write over extra chars */
                    306:                                                outchar(SP);
                    307:                                                z++; }
                    308:                                        bprintf("\x1b[%dD",z-i);        /* back to new x corridnant */
                    309:                                        l-=x-i; }                       /* l=new length */
                    310:                                else {
                    311:                                        while(i && str1[i-1]==SP) {
                    312:                                                i--;
                    313:                                                l--;
                    314:                                                if(!(mode&K_NOECHO))
                    315:                                                        bputs("\b \b"); }
                    316:                                        while(i && str1[i-1]!=SP) {
                    317:                                                i--;
                    318:                                                l--;
                    319:                                                if(!(mode&K_NOECHO))
                    320:                                                        bputs("\b \b"); } }
                    321:                                break;
                    322:                        case 24:    /* Ctrl-X   Delete entire line */
                    323:                                if(mode&K_NOECHO)
                    324:                                        l=0;
                    325:                                else {
                    326:                                        while(i<l) {
                    327:                                                outchar(SP);
                    328:                                                i++; }
                    329:                                        while(l) {
                    330:                                                l--;
                    331:                                                bputs("\b \b"); } }
                    332:                                i=0;
                    333:                                break;
                    334:                        case 25:    /* Ctrl-Y   Delete to end of line */
                    335:                                if(useron.misc&ANSI && !(mode&K_NOECHO)) {
                    336:                                        bputs("\x1b[K");
                    337:                                        l=i; }
                    338:                                break;
                    339:                        case 28:    /* Ctrl-\ Previous word */
                    340:                                if(i && (useron.misc&ANSI) && !(mode&K_NOECHO)) {
                    341:                                        x=i;
                    342:                                        while(str1[i-1]==SP && i)
                    343:                                                i--;
                    344:                                        while(str1[i-1]!=SP && i)
                    345:                                                i--;
                    346:                                        bprintf("\x1b[%dD",x-i); }
                    347:                                break;
                    348:                        case 29:  /* Ctrl-]/Left Arrow  Reverse Cursor Movement */
                    349:                                if(i && (useron.misc&ANSI) && !(mode&K_NOECHO)) {
                    350:                                        bputs("\x1b[D");   /* move cursor left one */
                    351:                                        i--; }
                    352:                                break;
                    353:                        case 30:  /* Ctrl-^/Up Arrow */
                    354:                                if(!(mode&K_EDIT))
                    355:                                        break;
                    356:                                if(i>l)
                    357:                                        l=i;
                    358:                                str1[l]=0;
                    359:                                strcpy(strout,str1);
                    360:                                if((stripattr(strout) || ins) && !(mode&K_NOECHO))
                    361:                                        redrwstr(strout,i,l,K_MSG);
                    362:                                if(mode&K_LINE && !(mode&K_NOECHO))
                    363:                                        attr(LIGHTGRAY);
                    364:                                console|=CON_UPARROW;
                    365:                                return(l);
                    366:                        case DEL:  /* Ctrl-BkSpc (DEL) Delete current char */
                    367:                                if(i==l) {      /* Backspace if end of line */
                    368:                                        if(i) {
                    369:                                                i--;
                    370:                                                l--;
                    371:                                                if(!(mode&K_NOECHO))
                    372:                                                        bputs("\b \b");
                    373:                                        }
                    374:                                        break;
                    375:                                }
                    376:                                l--;
                    377:                                z=i;
                    378:                                while(z<l)  {       /* move the characters in the line */
                    379:                                        outchar(str1[z]=str1[z+1]);
                    380:                                        z++; }
                    381:                                outchar(SP);        /* write over the last char */
                    382:                                bprintf("\x1b[%dD",(l-i)+1);
                    383:                                break;
                    384:                        default:
                    385:                                if(mode&K_WRAP && i==maxlen && ch>=SP && !ins) {
                    386:                                        str1[i]=0;
                    387:                                        if(ch==SP && !(mode&K_CHAT)) { /* don't wrap a space */ 
                    388:                                                strcpy(strout,str1);       /* as last char */
                    389:                                                if(stripattr(strout) && !(mode&K_NOECHO))
                    390:                                                        redrwstr(strout,i,l,K_MSG);
                    391:                                                if(!(mode&K_NOECHO))
                    392:                                                        CRLF;
                    393:                                                return(i); }
                    394:                                        x=i-1;
                    395:                                        z=1;
                    396:                                        wordwrap[0]=ch;
                    397:                                        while(str1[x]!=SP && x)
                    398:                                                wordwrap[z++]=str1[x--];
                    399:                                        if(x<(maxlen/2)) {
                    400:                                                wordwrap[1]=0;  /* only wrap one character */
                    401:                                                strcpy(strout,str1);
                    402:                                                if(stripattr(strout) && !(mode&K_NOECHO))
                    403:                                                        redrwstr(strout,i,l,K_MSG);
                    404:                                                if(!(mode&K_NOECHO))
                    405:                                                        CRLF;
                    406:                                                return(i); }
                    407:                                        wordwrap[z]=0;
                    408:                                        if(!(mode&K_NOECHO))
                    409:                                                while(z--) {
                    410:                                                        bputs("\b \b");
                    411:                                                        i--; }
                    412:                                        strrev(wordwrap);
                    413:                                        str1[x]=0;
                    414:                                        strcpy(strout,str1);
                    415:                                        if(stripattr(strout) && !(mode&K_NOECHO))
                    416:                                                redrwstr(strout,i,x,(char)mode);
                    417:                                        if(!(mode&K_NOECHO))
                    418:                                                CRLF;
                    419:                                        return(x); }
                    420:                                if(i<maxlen && ch>=SP) {
                    421:                                        if(mode&K_UPRLWR)
                    422:                                                if(!i || (i && (str1[i-1]==SP || str1[i-1]=='-'
                    423:                                                        || str1[i-1]=='.' || str1[i-1]=='_')))
                    424:                                                        ch=toupper(ch);
                    425:                                                else
                    426:                                                        ch=tolower(ch);
                    427:                                        if(ins) {
                    428:                                                if(l<maxlen)    /* l<maxlen */
                    429:                                                        l++;
                    430:                                                for(x=l;x>i;x--)
                    431:                                                        str1[x]=str1[x-1];
                    432:                                                rprintf("%.*s",l-i,str1+i);
                    433:                                                rprintf("\x1b[%dD",l-i);
                    434:                                                if(i==maxlen-1) {
                    435:                                                        bputs("  \b\b");
                    436:                                                        ins=0; } }
                    437:                                        str1[i++]=ch;
                    438:                                        if(!(mode&K_NOECHO))
                    439:                                                outchar(ch); } }
                    440:                if(i>l)
                    441:                        l=i;
                    442:                if(mode&K_CHAT && !l)
                    443:                        return(0); }
                    444:        if(!online)
                    445:                return(0);
                    446:        if(i>l)
                    447:                l=i;
                    448:        str1[l]=0;
                    449:        if(!(sys_status&SS_ABORT)) {
                    450:                strcpy(strout,str1);
                    451:                if((stripattr(strout) || ins) && !(mode&K_NOECHO))
                    452:                        redrwstr(strout,i,l,K_MSG); }
                    453:        else
                    454:                l=0;
                    455:        if(mode&K_LINE && !(mode&K_NOECHO)) attr(LIGHTGRAY);
                    456:        if(!(mode&(K_NOCRLF|K_NOECHO))) {
                    457:                outchar(CR);
                    458:                if(!(mode&K_MSG && sys_status&SS_ABORT))
                    459:                        outchar(LF);
                    460:                lncntr=0; }
                    461:        return(l);
                    462: }
                    463: 
                    464: /****************************************************************************/
                    465: /* Hot keyed number input routine.                                          */
                    466: /* Returns a valid number between 1 and max, 0 if no number entered, or -1  */
                    467: /* if the user hit 'Q' or ctrl-c                                            */
                    468: /****************************************************************************/
                    469: long sbbs_t::getnum(ulong max)
                    470: {
                    471:     uchar ch,n=0;
                    472:        long i=0;
                    473: 
                    474:        while(online) {
                    475:                ch=getkey(K_UPPER);
                    476:                if(ch>0x7f)
                    477:                        continue;
                    478:                if(ch=='Q') {
                    479:                        outchar('Q');
                    480:                        if(useron.misc&COLDKEYS)
                    481:                                ch=getkey(K_UPPER);
                    482:                        if(ch==BS) {
                    483:                                bputs("\b \b");
                    484:                                continue; }
                    485:                        CRLF;
                    486:                        lncntr=0;
                    487:                        return(-1); }
                    488:                else if(sys_status&SS_ABORT) {
                    489:                        CRLF;
                    490:                        lncntr=0;
                    491:                        return(-1); }
                    492:                else if(ch==CR) {
                    493:                        CRLF;
                    494:                        lncntr=0;
                    495:                        return(i); }
                    496:                else if(ch==BS && n) {
                    497:                        bputs("\b \b");
                    498:                        i/=10;
                    499:                        n--; }
                    500:                else if(isdigit(ch) && (i*10UL)+(ch&0xf)<=max && (ch!='0' || n)) {
                    501:                        i*=10L;
                    502:                        n++;
                    503:                        i+=ch&0xf;
                    504:                        outchar(ch);
                    505:                        if(i*10UL>max && !(useron.misc&COLDKEYS)) {
                    506:                                CRLF;
                    507:                                lncntr=0;
                    508:                                return(i); } } }
                    509:        return(0);
                    510: }

unix.superglobalmegacorp.com

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