Annotation of coherent/d/usr/bin/elvis/ex.c, revision 1.1.1.1

1.1       root        1: /* ex.c */
                      2: 
                      3: /* Author:
                      4:  *     Steve Kirkendall
                      5:  *     16820 SW Tallac Way
                      6:  *     Beaverton, OR 97006
                      7:  *     [email protected], or ...uunet!tektronix!psueea!jove!kirkenda
                      8:  */
                      9: 
                     10: 
                     11: /* This file contains the code for reading ex commands. */
                     12: 
                     13: #include "config.h"
                     14: #include <ctype.h>
                     15: #include "vi.h"
                     16: 
                     17: #ifndef isascii
                     18: # define isascii(c) !((c)&~0x7f)
                     19: #endif
                     20: 
                     21: /* This data type is used to describe the possible argument combinations */
                     22: typedef short ARGT;
                     23: #define FROM   1               /* allow a linespec */
                     24: #define        TO      2               /* allow a second linespec */
                     25: #define BANG   4               /* allow a ! after the command name */
                     26: #define EXTRA  8               /* allow extra args after command name */
                     27: #define XFILE  16              /* expand wildcards in extra part */
                     28: #define NOSPC  32              /* no spaces allowed in the extra part */
                     29: #define        DFLALL  64              /* default file range is 1,$ */
                     30: #define DFLNONE        128             /* no default file range */
                     31: #define NODFL  256             /* do not default to the current file name */
                     32: #define EXRCOK 512             /* can be in a .exrc file */
                     33: #define NL     1024            /* if mode!=MODE_EX, then write a newline first */
                     34: #define PLUS   2048            /* allow a line number, as in ":e +32 foo" */
                     35: #define ZERO   4096            /* allow 0 to be given as a line number */
                     36: #define FILES  (XFILE + EXTRA) /* multiple extra files allowed */
                     37: #define WORD1  (EXTRA + NOSPC) /* one extra word allowed */
                     38: #define FILE1  (FILES + NOSPC) /* 1 file allowed, defaults to current file */
                     39: #define NAMEDF (FILE1 + NODFL) /* 1 file allowed, defaults to "" */
                     40: #define NAMEDFS        (FILES + NODFL) /* multiple files allowed, default is "" */
                     41: #define RANGE  (FROM + TO)     /* range of linespecs allowed */
                     42: #define NONE   0               /* no args allowed at all */
                     43: 
                     44: /* This array maps ex command names to command codes. The order in which
                     45:  * command names are listed below is significant -- ambiguous abbreviations
                     46:  * are always resolved to be the first possible match.  (e.g. "r" is taken
                     47:  * to mean "read", not "rewind", because "read" comes before "rewind")
                     48:  */
                     49: static struct
                     50: {
                     51:        char    *name;  /* name of the command */
                     52:        CMD     code;   /* enum code of the command */
                     53:        void    (*fn)();/* function which executes the command */
                     54:        ARGT    argt;   /* command line arguments permitted/needed/used */
                     55: }
                     56:        cmdnames[] =
                     57: {   /* cmd name        cmd code        function        arguments */
                     58:        {"append",      CMD_APPEND,     cmd_append,     FROM+ZERO       },
                     59: #ifdef DEBUG
                     60:        {"bug",         CMD_DEBUG,      cmd_debug,      RANGE+BANG+EXTRA+NL},
                     61: #endif
                     62:        {"change",      CMD_CHANGE,     cmd_append,     RANGE           },
                     63:        {"delete",      CMD_DELETE,     cmd_delete,     RANGE+WORD1     },
                     64:        {"edit",        CMD_EDIT,       cmd_edit,       BANG+FILE1+PLUS },
                     65:        {"file",        CMD_FILE,       cmd_file,       NAMEDF          },
                     66:        {"global",      CMD_GLOBAL,     cmd_global,     RANGE+BANG+EXTRA+DFLALL},
                     67:        {"insert",      CMD_INSERT,     cmd_append,     FROM            },
                     68:        {"join",        CMD_INSERT,     cmd_join,       RANGE           },
                     69:        {"k",           CMD_MARK,       cmd_mark,       FROM+WORD1      },
                     70:        {"list",        CMD_LIST,       cmd_print,      RANGE+NL        },
                     71:        {"move",        CMD_MOVE,       cmd_move,       RANGE+EXTRA     },
                     72:        {"next",        CMD_NEXT,       cmd_next,       BANG+NAMEDFS    },
                     73:        {"Next",        CMD_PREVIOUS,   cmd_next,       BANG            },
                     74:        {"print",       CMD_PRINT,      cmd_print,      RANGE+NL        },
                     75:        {"quit",        CMD_QUIT,       cmd_xit,        BANG            },
                     76:        {"read",        CMD_READ,       cmd_read,       FROM+ZERO+NAMEDF},
                     77:        {"substitute",  CMD_SUBSTITUTE, cmd_substitute, RANGE+EXTRA     },
                     78:        {"to",          CMD_COPY,       cmd_move,       RANGE+EXTRA     },
                     79:        {"undo",        CMD_UNDO,       cmd_undo,       NONE            },
                     80:        {"vglobal",     CMD_VGLOBAL,    cmd_global,     RANGE+EXTRA+DFLALL},
                     81:        {"write",       CMD_WRITE,      cmd_write,      RANGE+BANG+FILE1+DFLALL},
                     82:        {"xit",         CMD_XIT,        cmd_xit,        BANG+NL         },
                     83:        {"yank",        CMD_YANK,       cmd_delete,     RANGE+WORD1     },
                     84: 
                     85:        {"!",           CMD_BANG,       cmd_shell,      EXRCOK+RANGE+NAMEDFS+DFLNONE+NL},
                     86:        {"<",           CMD_SHIFTL,     cmd_shift,      RANGE           },
                     87:        {">",           CMD_SHIFTR,     cmd_shift,      RANGE           },
                     88:        {"=",           CMD_EQUAL,      cmd_file,       RANGE           },
                     89:        {"&",           CMD_SUBAGAIN,   cmd_substitute, RANGE           },
                     90: #ifndef NO_AT
                     91:        {"@",           CMD_AT,         cmd_at,         EXTRA           },
                     92: #endif
                     93: 
                     94: #ifndef NO_ABBR
                     95:        {"abbreviate",  CMD_ABBR,       cmd_abbr,       EXRCOK+EXTRA    },
                     96: #endif
                     97:        {"args",        CMD_ARGS,       cmd_args,       EXRCOK+NAMEDFS  },
                     98: #ifndef NO_ERRLIST
                     99:        {"cc",          CMD_CC,         cmd_make,       BANG+FILES      },
                    100: #endif
                    101:        {"cd",          CMD_CD,         cmd_cd,         EXRCOK+NAMEDF   },
                    102:        {"copy",        CMD_COPY,       cmd_move,       RANGE+EXTRA     },
                    103: #ifndef NO_DIGRAPH
                    104:        {"digraph",     CMD_DIGRAPH,    cmd_digraph,    EXRCOK+BANG+EXTRA},
                    105: #endif
                    106: #ifndef NO_ERRLIST
                    107:        {"errlist",     CMD_ERRLIST,    cmd_errlist,    BANG+NAMEDF     },
                    108: #endif
                    109:        {"ex",          CMD_EDIT,       cmd_edit,       BANG+FILE1      },
                    110:        {"map",         CMD_MAP,        cmd_map,        EXRCOK+BANG+EXTRA},
                    111: #ifndef NO_MKEXRC
                    112:        {"mkexrc",      CMD_MKEXRC,     cmd_mkexrc,     NAMEDF          },
                    113: #endif
                    114:        {"number",      CMD_NUMBER,     cmd_print,      RANGE+NL        },
                    115:        {"put",         CMD_PUT,        cmd_put,        FROM+ZERO+WORD1 },
                    116:        {"set",         CMD_SET,        cmd_set,        EXRCOK+EXTRA    },
                    117:        {"shell",       CMD_SHELL,      cmd_shell,      NL              },
                    118:        {"source",      CMD_SOURCE,     cmd_source,     EXRCOK+NAMEDF   },
                    119:        {"tag",         CMD_TAG,        cmd_tag,        BANG+WORD1      },
                    120:        {"version",     CMD_VERSION,    cmd_version,    EXRCOK+NONE     },
                    121:        {"visual",      CMD_VISUAL,     cmd_visual,     NONE            },
                    122:        {"wq",          CMD_WQUIT,      cmd_xit,        NL              },
                    123: 
                    124: #ifdef DEBUG
                    125:        {"debug",       CMD_DEBUG,      cmd_debug,      RANGE+BANG+EXTRA+NL},
                    126:        {"validate",    CMD_VALIDATE,   cmd_validate,   BANG+NL         },
                    127: #endif
                    128:        {"chdir",       CMD_CD,         cmd_cd,         EXRCOK+NAMEDF   },
                    129: #ifndef NO_ERRLIST
                    130:        {"make",        CMD_MAKE,       cmd_make,       BANG+NAMEDFS    },
                    131: #endif
                    132:        {"mark",        CMD_MARK,       cmd_mark,       FROM+WORD1      },
                    133:        {"previous",    CMD_PREVIOUS,   cmd_next,       BANG            },
                    134:        {"rewind",      CMD_REWIND,     cmd_next,       BANG            },
                    135:        {"unmap",       CMD_UNMAP,      cmd_map,        EXRCOK+BANG+EXTRA},
                    136: #ifndef NO_ABBR
                    137:        {"unabbreviate",CMD_UNABBR,     cmd_abbr,       EXRCOK+WORD1    },
                    138: #endif
                    139: 
                    140:        {(char *)0}
                    141: };
                    142: 
                    143: 
                    144: /* This function parses a search pattern - given a pointer to a / or ?,
                    145:  * it replaces the ending / or ? with a \0, and returns a pointer to the
                    146:  * stuff that came after the pattern.
                    147:  */
                    148: char   *parseptrn(ptrn)
                    149:        REG char        *ptrn;
                    150: {
                    151:        REG char        *scan;
                    152: 
                    153:        for (scan = ptrn + 1;
                    154:             *scan && *scan != *ptrn;
                    155:             scan++)
                    156:        {
                    157:                /* allow backslashed versions of / and ? in the pattern */
                    158:                if (*scan == '\\' && scan[1] != '\0')
                    159:                {
                    160:                        scan++;
                    161:                }
                    162:        }
                    163:        if (*scan)
                    164:        {
                    165:                *scan++ = '\0';
                    166:        }
                    167: 
                    168:        return scan;
                    169: }
                    170: 
                    171: 
                    172: /* This function parses a line specifier for ex commands */
                    173: char *linespec(s, markptr)
                    174:        REG char        *s;             /* start of the line specifier */
                    175:        MARK            *markptr;       /* where to store the mark's value */
                    176: {
                    177:        long            num;
                    178:        REG char        *t;
                    179: 
                    180:        /* parse each ;-delimited clause of this linespec */
                    181:        do
                    182:        {
                    183:                /* skip an initial ';', if any */
                    184:                if (*s == ';')
                    185:                {
                    186:                        s++;
                    187:                }
                    188: 
                    189:                /* skip leading spaces */
                    190:                while (isascii(*s) && isspace(*s))
                    191:                {
                    192:                        s++;
                    193:                }
                    194:        
                    195:                /* dot means current position */
                    196:                if (*s == '.')
                    197:                {
                    198:                        s++;
                    199:                        *markptr = cursor;
                    200:                }
                    201:                /* '$' means the last line */
                    202:                else if (*s == '$')
                    203:                {
                    204:                        s++;
                    205:                        *markptr = MARK_LAST;
                    206:                }
                    207:                /* digit means an absolute line number */
                    208:                else if (isascii(*s) && isdigit(*s))
                    209:                {
                    210:                        for (num = 0; isascii(*s) && isdigit(*s); s++)
                    211:                        {
                    212:                                num = num * 10 + *s - '0';
                    213:                        }
                    214:                        *markptr = MARK_AT_LINE(num);
                    215:                }
                    216:                /* appostrophe means go to a set mark */
                    217:                else if (*s == '\'')
                    218:                {
                    219:                        s++;
                    220:                        *markptr = m_tomark(cursor, 1L, (int)*s);
                    221:                        s++;
                    222:                }
                    223:                /* slash means do a search */
                    224:                else if (*s == '/' || *s == '?')
                    225:                {
                    226:                        /* put a '\0' at the end of the search pattern */
                    227:                        t = parseptrn(s);
                    228:        
                    229:                        /* search for the pattern */
                    230:                        *markptr &= ~(BLKSIZE - 1);
                    231:                        if (*s == '/')
                    232:                        {
                    233:                                pfetch(markline(*markptr));
                    234:                                if (plen > 0)
                    235:                                        *markptr += plen - 1;
                    236:                                *markptr = m_fsrch(*markptr, s);
                    237:                        }
                    238:                        else
                    239:                        {
                    240:                                *markptr = m_bsrch(*markptr, s);
                    241:                        }
                    242:        
                    243:                        /* adjust command string pointer */
                    244:                        s = t;
                    245:                }
                    246:        
                    247:                /* if linespec was faulty, quit now */
                    248:                if (!*markptr)
                    249:                {
                    250:                        return s;
                    251:                }
                    252:        
                    253:                /* maybe add an offset */
                    254:                t = s;
                    255:                if (*t == '-' || *t == '+')
                    256:                {
                    257:                        s++;
                    258:                        for (num = 0; *s >= '0' && *s <= '9'; s++)
                    259:                        {
                    260:                                num = num * 10 + *s - '0';
                    261:                        }
                    262:                        if (num == 0)
                    263:                        {
                    264:                                num = 1;
                    265:                        }
                    266:                        *markptr = m_updnto(*markptr, num, *t);
                    267:                }
                    268:        } while (*s == ';' || *s == '+' || *s == '-');
                    269: 
                    270:        return s;
                    271: }
                    272: 
                    273: 
                    274: 
                    275: /* This function reads an ex command and executes it. */
                    276: void ex()
                    277: {
                    278:        char            cmdbuf[80];
                    279:        REG int         cmdlen;
                    280:        static long     oldline;
                    281:        
                    282:        significant = FALSE;
                    283:        oldline = markline(cursor);
                    284: 
                    285:        while (mode == MODE_EX)
                    286:        {
                    287:                /* read a line */
                    288:                cmdlen = vgets(':', cmdbuf, sizeof cmdbuf);
                    289:                if (cmdlen < 0)
                    290:                {
                    291:                        return;
                    292:                }
                    293: 
                    294:                /* if empty line, assume ".+1" */
                    295:                if (cmdlen == 0)
                    296:                {
                    297:                        strcpy(cmdbuf, ".+1");
                    298:                        qaddch('\r');
                    299:                        clrtoeol();
                    300:                }
                    301:                else
                    302:                {
                    303:                        addch('\n');
                    304:                }
                    305:                refresh();
                    306: 
                    307:                /* parse & execute the command */
                    308:                doexcmd(cmdbuf);
                    309: 
                    310:                /* handle autoprint */
                    311:                if (significant || markline(cursor) != oldline)
                    312:                {
                    313:                        significant = FALSE;
                    314:                        oldline = markline(cursor);
                    315:                        if (*o_autoprint && mode == MODE_EX)
                    316:                        {
                    317:                                cmd_print(cursor, cursor, CMD_PRINT, FALSE, "");
                    318:                        }
                    319:                }
                    320:        }
                    321: }
                    322: 
                    323: void doexcmd(cmdbuf)
                    324:        char            *cmdbuf;        /* string containing an ex command */
                    325: {
                    326:        REG char        *scan;          /* used to scan thru cmdbuf */
                    327:        MARK            frommark;       /* first linespec */
                    328:        MARK            tomark;         /* second linespec */
                    329:        REG int         cmdlen;         /* length of the command name given */
                    330:        CMD             cmd;            /* what command is this? */
                    331:        ARGT            argt;           /* argument types for this command */
                    332:        short           forceit;        /* bang version of a command? */
                    333:        REG int         cmdidx;         /* index of command */
                    334:        REG char        *build;         /* used while copying filenames */
                    335:        int             iswild;         /* boolean: filenames use wildcards? */
                    336:        int             isdfl;          /* using default line ranges? */
                    337:        int             didsub;         /* did we substitute file names for % or # */
                    338: 
                    339: 
                    340:        /* ex commands can't be undone via the shift-U command */
                    341:        U_line = 0L;
                    342: 
                    343:        /* ignore command lines that start with a double-quote */
                    344:        if (*cmdbuf == '"')
                    345:        {
                    346:                return;
                    347:        }
                    348: 
                    349:        /* permit extra colons at the start of the line */
                    350:        while (*cmdbuf == ':')
                    351:        {
                    352:                cmdbuf++;
                    353:        }
                    354: 
                    355:        /* parse the line specifier */
                    356:        scan = cmdbuf;
                    357:        if (nlines < 1)
                    358:        {
                    359:                /* no file, so don't allow addresses */
                    360:        }
                    361:        else if (*scan == '%')
                    362:        {
                    363:                /* '%' means all lines */
                    364:                frommark = MARK_FIRST;
                    365:                tomark = MARK_LAST;
                    366:                scan++;
                    367:        }
                    368:        else if (*scan == '0')
                    369:        {
                    370:                frommark = tomark = MARK_UNSET;
                    371:                scan++;
                    372:        }
                    373:        else
                    374:        {
                    375:                frommark = cursor;
                    376:                scan = linespec(scan, &frommark);
                    377:                tomark = frommark;
                    378:                if (frommark && *scan == ',')
                    379:                {
                    380:                        scan++;
                    381:                        scan = linespec(scan, &tomark);
                    382:                }
                    383:                if (!tomark)
                    384:                {
                    385:                        /* faulty line spec -- fault already described */
                    386:                        return;
                    387:                }
                    388:                if (frommark > tomark)
                    389:                {
                    390:                        msg("first address exceeds the second");
                    391:                        return;
                    392:                }
                    393:        }
                    394:        isdfl = (scan == cmdbuf);
                    395: 
                    396:        /* skip whitespace */
                    397:        while (isascii(*scan) && isspace(*scan))
                    398:        {
                    399:                scan++;
                    400:        }
                    401: 
                    402:        /* if no command, then just move the cursor to the mark */
                    403:        if (!*scan)
                    404:        {
                    405:                cursor = tomark;
                    406:                return;
                    407:        }
                    408: 
                    409:        /* figure out how long the command name is */
                    410:        if (isascii(*scan) && !isalpha(*scan))
                    411:        {
                    412:                cmdlen = 1;
                    413:        }
                    414:        else
                    415:        {
                    416:                for (cmdlen = 1;
                    417:                     !isascii(scan[cmdlen]) || isalpha(scan[cmdlen]);
                    418:                     cmdlen++)
                    419:                {
                    420:                }
                    421:        }
                    422: 
                    423:        /* lookup the command code */
                    424:        for (cmdidx = 0;
                    425:             cmdnames[cmdidx].name && strncmp(scan, cmdnames[cmdidx].name, cmdlen);
                    426:             cmdidx++)
                    427:        {
                    428:        }
                    429:        argt = cmdnames[cmdidx].argt;
                    430:        cmd = cmdnames[cmdidx].code;
                    431:        if (cmd == CMD_NULL)
                    432:        {
                    433: #if OSK
                    434:                msg("Unknown command \"%s\"", scan);
                    435: #else
                    436:                msg("Unknown command \"%.*s\"", cmdlen, scan);
                    437: #endif
                    438:                return;
                    439:        }
                    440: 
                    441:        /* if the command ended with a bang, set the forceit flag */
                    442:        scan += cmdlen;
                    443:        if ((argt & BANG) && *scan == '!')
                    444:        {
                    445:                scan++;
                    446:                forceit = 1;
                    447:        }
                    448:        else
                    449:        {
                    450:                forceit = 0;
                    451:        }
                    452: 
                    453:        /* skip any more whitespace, to leave scan pointing to arguments */
                    454:        while (isascii(*scan) && isspace(*scan))
                    455:        {
                    456:                scan++;
                    457:        }
                    458: 
                    459:        /* a couple of special cases for filenames */
                    460:        if (argt & XFILE)
                    461:        {
                    462:                /* if names were given, process them */
                    463:                if (*scan)
                    464:                {
                    465:                        for (build = tmpblk.c, iswild = didsub = FALSE; *scan; scan++)
                    466:                        {
                    467:                                switch (*scan)
                    468:                                {
                    469:                                  case '%':
                    470:                                        if (!*origname)
                    471:                                        {
                    472:                                                msg("No filename to substitute for %%");
                    473:                                                return;
                    474:                                        }
                    475:                                        strcpy(build, origname);
                    476:                                        while (*build)
                    477:                                        {
                    478:                                                build++;
                    479:                                        }
                    480:                                        didsub = TRUE;
                    481:                                        break;
                    482:        
                    483:                                  case '#':
                    484:                                        if (!*prevorig)
                    485:                                        {
                    486:                                                msg("No filename to substitute for #");
                    487:                                                return;
                    488:                                        }
                    489:                                        strcpy(build, prevorig);
                    490:                                        while (*build)
                    491:                                        {
                    492:                                                build++;
                    493:                                        }
                    494:                                        didsub = TRUE;
                    495:                                        break;
                    496:        
                    497:                                  case '*':
                    498:                                  case '?':
                    499: #if !(MSDOS || TOS)
                    500:                                  case '[':
                    501:                                  case '`':
                    502:                                  case '{': /* } */
                    503:                                  case '$':
                    504:                                  case '~':
                    505: #endif
                    506:                                        *build++ = *scan;
                    507:                                        iswild = TRUE;
                    508:                                        break;
                    509: 
                    510:                                  default:
                    511:                                        *build++ = *scan;
                    512:                                }
                    513:                        }
                    514:                        *build = '\0';
                    515:        
                    516:                        if (cmd == CMD_BANG
                    517:                         || cmd == CMD_READ && tmpblk.c[0] == '!'
                    518:                         || cmd == CMD_WRITE && tmpblk.c[0] == '!')
                    519:                        {
                    520:                                if (didsub)
                    521:                                {
                    522:                                        if (mode != MODE_EX)
                    523:                                        {
                    524:                                                addch('\n');
                    525:                                        }
                    526:                                        addstr(tmpblk.c);
                    527:                                        addch('\n');
                    528:                                        exrefresh();
                    529:                                }
                    530:                        }
                    531:                        else
                    532:                        {
                    533:                                if (iswild && tmpblk.c[0] != '>')
                    534:                                {
                    535:                                        scan = wildcard(tmpblk.c);
                    536:                                }
                    537:                        }
                    538:                }
                    539:                else /* no names given, maybe assume origname */
                    540:                {
                    541:                        if (!(argt & NODFL))
                    542:                        {
                    543:                                strcpy(tmpblk.c, origname);
                    544:                        }
                    545:                        else
                    546:                        {
                    547:                                *tmpblk.c = '\0';
                    548:                        }
                    549:                }
                    550: 
                    551:                scan = tmpblk.c;
                    552:        }
                    553: 
                    554:        /* bad arguments? */
                    555:        if (!(argt & EXRCOK) && nlines < 1L)
                    556:        {
                    557:                msg("Can't use the \"%s\" command in a %s file", cmdnames[cmdidx].name, EXRC);
                    558:                return;
                    559:        }
                    560:        if (!(argt & (ZERO | EXRCOK)) && frommark == MARK_UNSET)
                    561:        {
                    562:                msg("Can't use address 0 with \"%s\" command.", cmdnames[cmdidx].name);
                    563:                return;
                    564:        }
                    565:        if (!(argt & FROM) && frommark != cursor && nlines >= 1L)
                    566:        {
                    567:                msg("Can't use address with \"%s\" command.", cmdnames[cmdidx].name);
                    568:                return;
                    569:        }
                    570:        if (!(argt & TO) && tomark != frommark && nlines >= 1L)
                    571:        {
                    572:                msg("Can't use a range with \"%s\" command.", cmdnames[cmdidx].name);
                    573:                return;
                    574:        }
                    575:        if (!(argt & EXTRA) && *scan)
                    576:        {
                    577:                msg("Extra characters after \"%s\" command.", cmdnames[cmdidx].name);
                    578:                return;
                    579:        }
                    580:        if ((argt & NOSPC) && !(cmd == CMD_READ && (forceit || *scan == '!')))
                    581:        {
                    582:                build = scan;
                    583: #ifndef CRUNCH
                    584:                if ((argt & PLUS) && *build == '+')
                    585:                {
                    586:                        while (*build && !(isascii(*build) && isspace(*build)))
                    587:                        {
                    588:                                build++;
                    589:                        }
                    590:                        while (*build && isascii(*build) && isspace(*build))
                    591:                        {
                    592:                                build++;
                    593:                        }
                    594:                }
                    595: #endif /* not CRUNCH */
                    596:                for (; *build; build++)
                    597:                {
                    598:                        if (isspace(*build))
                    599:                        {
                    600:                                msg("Too many %s to \"%s\" command.",
                    601:                                        (argt & XFILE) ? "filenames" : "arguments",
                    602:                                        cmdnames[cmdidx].name);
                    603:                                return;
                    604:                        }
                    605:                }
                    606:        }
                    607: 
                    608:        /* some commands have special default ranges */
                    609:        if (isdfl && (argt & DFLALL))
                    610:        {
                    611:                frommark = MARK_FIRST;
                    612:                tomark = MARK_LAST;
                    613:        }
                    614:        else if (isdfl && (argt & DFLNONE))
                    615:        {
                    616:                frommark = tomark = 0L;
                    617:        }
                    618: 
                    619:        /* write a newline if called from visual mode */
                    620:        if ((argt & NL) && mode != MODE_EX && !exwrote)
                    621:        {
                    622:                addch('\n');
                    623:                exrefresh();
                    624:        }
                    625: 
                    626:        /* act on the command */
                    627:        (*cmdnames[cmdidx].fn)(frommark, tomark, cmd, forceit, scan);
                    628: }
                    629: 
                    630: 
                    631: /* This function executes EX commands from a file.  It returns 1 normally, or
                    632:  * 0 if the file could not be opened for reading.
                    633:  */
                    634: int doexrc(filename)
                    635:        char    *filename;      /* name of a ".exrc" file */
                    636: {
                    637:        int     fd;             /* file descriptor */
                    638:        int     len;            /* length of the ".exrc" file */
                    639:        char    buf[MAXRCLEN];  /* buffer, holds the entire .exrc file */
                    640: 
                    641:        /* open the file, read it, and close */
                    642:        fd = open(filename, O_RDONLY);
                    643:        if (fd < 0)
                    644:        {
                    645:                return 0;
                    646:        }
                    647:        len = tread(fd, buf, MAXRCLEN);
                    648:        close(fd);
                    649: 
                    650:        /* execute the string */
                    651:        exstring(buf, len);
                    652: 
                    653:        return 1;
                    654: }
                    655: 
                    656: void exstring(buf, len)
                    657:        char    *buf;   /* the commands to execute */
                    658:        int     len;    /* the length of the string */
                    659: {
                    660:        char    *cmd;           /* start of a command */
                    661:        char    *end;           /* used to search for the end of cmd */
                    662: 
                    663:        /* find & do each command */
                    664:        for (cmd = buf; cmd < &buf[len]; cmd = end + 1)
                    665:        {
                    666:                /* find the end of the command */
                    667:                for (end = cmd; *end != '\n' && *end != '|'; end++)
                    668:                {
                    669:                }
                    670:                *end = '\0';
                    671: 
                    672:                /* do it */
                    673:                doexcmd(cmd);
                    674:        }
                    675: }

unix.superglobalmegacorp.com

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