Annotation of coherent/d/usr/bin/elvis/ex.c, revision 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.