Annotation of coherent/g/usr/bin/me/bracket.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * This routine gets a bracket character from where the dot lies
                      3:  * and searches for the corresponding bracket.
                      4:  */
                      5: #include       <stdio.h>
                      6: #include       "ed.h"
                      7: 
                      8: static int o_col, o_row, r_col, r_char, r_row = -1;
                      9: 
                     10: /*
                     11:  * This is called before each comand is executed.
                     12:  */
                     13: bracketoff()
                     14: {
                     15:        if (bind.bracket && (r_row >= 0)) {
                     16:                tmove(r_row, r_col);
                     17:                tputc(r_char);
                     18:                r_row = -1;
                     19:                tmove(o_row, o_col);
                     20:                return (TRUE);
                     21:        }
                     22:        return (FALSE);
                     23: }
                     24: 
                     25: /*
                     26:  * toggle bracket mode.
                     27:  */
                     28: bracketsw()
                     29: {
                     30:        bind.bracket ^= 1;
                     31: }
                     32: 
                     33: bracketsearch()
                     34: {
                     35:        bstart(0);      /* do full search */
                     36: }
                     37: 
                     38: /*
                     39:  * This is called after each screen update.
                     40:  */
                     41: bracketmode(row, col)
                     42: {
                     43:        r_row = -1;
                     44:        if (bind.bracket)
                     45:                bstart(1);
                     46:        movecursor(row, col);
                     47:        tmove(o_row = row, o_col = col);
                     48: }
                     49: 
                     50: static
                     51: bstart(modesw)
                     52: {
                     53:        register LINE   *clp;
                     54:        int     cbo;
                     55: 
                     56:        if (((o_col = cbo = curwp->w_doto) == llength(clp = curwp->w_dotp)))
                     57:                if (modesw)
                     58:                        --cbo;
                     59:                else
                     60:                        return (FALSE);
                     61: 
                     62:        switch (lgetc(clp, cbo)) {
                     63:        case '/':
                     64:                if ((++cbo == llength(clp)) || ('*' != lgetc(clp, cbo--)))
                     65:                        break;
                     66:        case '[':
                     67:        case '{':
                     68:        case '(':
                     69:                return (brksearch(1, modesw, clp, cbo));
                     70:        case '*':
                     71:                if ((++cbo == llength(clp)) || ('/' != lgetc(clp, cbo)))
                     72:                        break;
                     73:        case ']':
                     74:        case '}':
                     75:        case ')':
                     76:                return (brksearch(-1, modesw, clp, cbo));
                     77:        case '"':
                     78:        case '\'':
                     79:                if (modesw)
                     80:                        break;
                     81:                if (mlyesno("Forward search"))
                     82:                        return (brksearch(1, modesw, clp, cbo));
                     83:                return (brksearch(-1, modesw, clp, cbo));
                     84:        }
                     85:        if (!modesw)
                     86:                mlwrite("Place dot on \"'(){}[] /* or */");
                     87:        return (FALSE);
                     88: }
                     89: 
                     90: /* defines for states of forward and backward searches */
                     91: #define NORMAL         0       /* normal state */
                     92: #define SLASH          1       /* slash maybe comment */
                     93: #define COMMENT        2       /* comment */
                     94: #define STAR           3       /* star in comment */
                     95: #define DQUOTE         4       /* in string */
                     96: #define SQUOTE         5       /* in single quote */
                     97: #define BSL                    6       /* backslash */
                     98: #define BADEXPR        7       /* bad expression encountered */
                     99: #define STARTB         8       /* starting search */
                    100: 
                    101: /*
                    102:  * scan for end of balanced c expression forward or backward.
                    103:  */
                    104: static
                    105: brksearch(dir, mode, clp, cbo)
                    106: int dir;       /* 1 forward -1 backward */
                    107: int mode;      /* 1 paren mode, 0 match paren command */
                    108: LINE *clp;     /* line to start search */
                    109: int cbo;       /* char to start search */
                    110: {
                    111:        register int c, state;
                    112:        LINE *end;
                    113:        int prev, pstate, bcnt, pcnt, ccnt, bscnt, ctrs;
                    114: 
                    115:        bcnt = ccnt = pcnt = bscnt = 0;
                    116:        state = STARTB;
                    117:        if (mode) {     /* end is top or bottom of window */
                    118:                if (dir < 0)
                    119:                        end = lback(curwp->w_linep);
                    120:                else
                    121:                        for (end = curwp->w_linep, c = curwp->w_ntrows;
                    122:                            (c-- > 0) && (curbp->b_linep != end);
                    123:                            end = lforw(end)) ;
                    124:        } else  /* end is buffer end */
                    125:                end = curbp->b_linep;
                    126: 
                    127:        while (clp != end) {
                    128:                if (dir > 0) { /* get next char */
                    129:                        if (cbo == llength(clp)) {
                    130:                                clp = lforw(clp);
                    131:                                cbo = 0;
                    132:                                c = '\n';
                    133:                        } else
                    134:                                c = lgetc(clp, cbo++);
                    135:                } else { /* get prev char. watch \ here. */
                    136:                        c = prev;
                    137:                        if (cbo < 0) {
                    138:                                clp = lback(clp);
                    139:                                cbo = llength(clp) - 1;
                    140:                                prev = '\n';
                    141:                        }
                    142:                        else if (('\\' == (prev = lgetc(clp, cbo--))) &&
                    143:                                (state != COMMENT) && (state != SLASH)) {
                    144:                                bscnt ^= 1;     /* count \ */
                    145:                                prev = c; /* don't discard char */
                    146:                                continue;
                    147:                        }
                    148:                        if (bscnt) { /* odd \ discard c */
                    149:                                bscnt = 0;
                    150:                                continue;
                    151:                        }
                    152:                }
                    153: 
                    154:                switch (state) {        /* do state processing */
                    155:                case SLASH:             /* / encountered */
                    156:                        if (c == '*') {
                    157:                                state = COMMENT;
                    158:                                continue;
                    159:                        }
                    160:                        state = NORMAL;
                    161:                case NORMAL:            /* not in anything */
                    162:                        break;
                    163:                case STAR:              /* * in comment */
                    164:                        if (c == '/') {
                    165:                                state = NORMAL;
                    166:                                goto processed;
                    167:                        }
                    168:                        state = COMMENT;
                    169:                case COMMENT:           /* in comment */
                    170:                        if (c == '*')
                    171:                                state = STAR;
                    172:                        continue;
                    173:                case SQUOTE:            /* in ' string */
                    174:                case DQUOTE:            /* in " string */
                    175:                        switch (c) {
                    176:                        case '\n':
                    177:                                state = BADEXPR;
                    178:                                goto processed;
                    179:                        case '\\':      /* can't get here if dir < 0 */
                    180:                                pstate = state;
                    181:                                state = BSL;
                    182:                                continue;
                    183:                        case '"':
                    184:                                if (state != DQUOTE)
                    185:                                        continue;
                    186:                                state = NORMAL;
                    187:                                goto processed;
                    188:                        case '\'':
                    189:                                if (state != SQUOTE)
                    190:                                        continue;
                    191:                                state = NORMAL;
                    192:                                goto processed;
                    193:                        default:
                    194:                                continue;
                    195:                        }
                    196:                case BSL:       /* can't get here if dir < 0 */
                    197:                        state = pstate;
                    198:                        continue;
                    199:                case STARTB:
                    200:                        state = NORMAL;
                    201:                        if (dir < 0)
                    202:                                continue;
                    203:                }       
                    204: 
                    205:                switch (c) { /* process chars in NORMAL state */
                    206:                case '[':
                    207:                        bcnt += dir;
                    208:                        break;
                    209:                case '{':
                    210:                        ccnt += dir;
                    211:                        if (pcnt | bcnt)
                    212:                                state = BADEXPR;
                    213:                        break;
                    214:                case ';':
                    215:                        if (bcnt)
                    216:                                state = BADEXPR;
                    217:                        break;
                    218:                case '(':
                    219:                        pcnt += dir;
                    220:                        break;
                    221:                case '"':
                    222:                        state = DQUOTE;
                    223:                        continue;
                    224:                case '\'':
                    225:                        state = SQUOTE;
                    226:                        continue;
                    227:                case '\\':      /* can't get here if dir < 0 */
                    228:                        pstate = state;
                    229:                        state = BSL;
                    230:                        continue;
                    231:                case '/':
                    232:                        state = SLASH;
                    233:                        continue;
                    234:                case ']':
                    235:                        bcnt -= dir;
                    236:                        break;
                    237:                case '}':
                    238:                        ccnt -= dir;
                    239:                        if (pcnt | bcnt)
                    240:                                state = BADEXPR;
                    241:                        break;
                    242:                case ')':
                    243:                        pcnt -= dir;
                    244:                }
                    245: 
                    246:                /* done if BADEXPR or balanced expr or ) with no ( etc */
                    247: processed:     if (((ctrs = bcnt | ccnt | pcnt) <= 0) || (state == BADEXPR)) {
                    248:                        if (dir > 0) {
                    249:                                if (--cbo < 0) {
                    250:                                        clp = lback(clp);
                    251:                                        cbo = llength(clp);
                    252:                                }
                    253:                        } else { /* we are on prev so back up 2 */
                    254:                                for (bscnt = 0; bscnt < 2; bscnt++) {
                    255:                                        if (++cbo > llength(clp)) {
                    256:                                                clp = lforw(clp);
                    257:                                                cbo = 0;
                    258:                                                break;
                    259:                                        }
                    260:                                }
                    261:                        }
                    262:                        if (mode) { /* paren mode */
                    263:                                if ((ctrs < 0) || (state == BADEXPR) ||
                    264:                                   (0 > (r_row = locatecursor(clp))))
                    265:                                        return (FALSE);
                    266:                                tmove(r_row, (r_col = truecol(clp, cbo)));
                    267:                                tstand(1);
                    268:                                tputc(r_char = c);
                    269:                                tstand(0);
                    270:                        } else { /* match paren command */
                    271:                                curwp->w_dotp = clp;
                    272:                                curwp->w_doto = cbo;
                    273:                                curwp->w_flag |= WFMOVE;
                    274:                                if ((ctrs < 0) || (state == BADEXPR)) {
                    275:                                        mlwrite("Bad expression");
                    276:                                        return (FALSE);
                    277:                                }
                    278:                        }
                    279:                        return (TRUE);
                    280:                }
                    281:        }
                    282:        if (!mode)
                    283:                mlwrite("End not found");
                    284:        return (FALSE);
                    285: }

unix.superglobalmegacorp.com

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