home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume11 / stevie3.69a / part02 < prev    next >
Encoding:
Text File  |  1990-03-10  |  61.0 KB  |  2,692 lines

  1. Newsgroups: comp.sources.misc
  2. organization: AT&T Bell Labs - Lincroft, NJ
  3. subject: v11i010: Stevie 3.69a - 2/6
  4. from: dmt@pegasus.ATT.COM (Dave Tutelman)
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 11, Issue 10
  8. Submitted-by: dmt@pegasus.ATT.COM (Dave Tutelman)
  9. Archive-name: stevie3.69a/part02
  10.  
  11. : This is a shar archive.  Extract with sh, not csh.
  12. : The rest of this file will extract:
  13. : alloc.c cmdline.c edit.c enveval.c fileio.c help.c hexchars.c env.h keymap.h ops.h param.h regexp.h regmagic.h
  14. echo extracting - alloc.c
  15. sed 's/^X//' > alloc.c << '!EOR!'
  16. X/* $Header: /nw/tony/src/stevie/src/RCS/alloc.c,v 1.5 89/08/06 09:49:22 tony Exp $
  17. X *
  18. X * Various allocation routines and routines returning information about
  19. X * allocated objects.
  20. X */
  21. X
  22. X#include "stevie.h"
  23. X
  24. Xchar *
  25. Xalloc(size)
  26. Xunsigned size;
  27. X{
  28. X    char    *p;        /* pointer to new storage space */
  29. X
  30. X    p = malloc(size);
  31. X    if ( p == (char *)NULL ) {    /* if there is no more room... */
  32. X        emsg("alloc() is unable to find memory!");
  33. X    }
  34. X    return(p);
  35. X}
  36. X
  37. Xchar *
  38. Xstrsave(string)
  39. Xchar    *string;
  40. X{
  41. X    return(strcpy(alloc((unsigned)(strlen(string)+1)),string));
  42. X}
  43. X
  44. Xscreenalloc()
  45. X{
  46. X    /*
  47. X     * If we're changing the size of the screen, free the old arrays
  48. X     */
  49. X    if (Realscreen != NULL)
  50. X        free(Realscreen);
  51. X    if (Nextscreen != NULL)
  52. X        free(Nextscreen);
  53. X
  54. X    Realscreen = malloc((unsigned)(Rows*Columns));
  55. X    Nextscreen = malloc((unsigned)(Rows*Columns));
  56. X    if (!Realscreen || !Nextscreen)
  57. X        return (-1);
  58. X    else    return (0);
  59. X}
  60. X
  61. X/*
  62. X * Allocate and initialize a new line structure with room for
  63. X * 'nchars'+1 characters. We add one to nchars here to allow for
  64. X * null termination because all the callers would just do it otherwise.
  65. X */
  66. XLINE *
  67. Xnewline(nchars)
  68. Xint    nchars;
  69. X{
  70. X    register LINE    *l;
  71. X
  72. X    if ((l = (LINE *) alloc(sizeof(LINE))) == NULL)
  73. X        return (LINE *) NULL;
  74. X
  75. X    l->s = alloc((unsigned) (nchars+1));    /* the line is empty */
  76. X    if (l->s == NULL)    return (LINE *) NULL;
  77. X    l->s[0] = NUL;
  78. X    l->size = nchars + 1;
  79. X
  80. X    l->prev = (LINE *) NULL;    /* should be initialized by caller */
  81. X    l->next = (LINE *) NULL;
  82. X
  83. X    return l;
  84. X}
  85. X
  86. X/*
  87. X * filealloc() - construct an initial empty file buffer
  88. X */
  89. Xvoid
  90. Xfilealloc()
  91. X{
  92. X    if ((Filemem->linep = newline(0)) == NULL) {
  93. X        fprintf(stderr,"Unable to allocate file memory!\n");
  94. X        exit(1);
  95. X    }
  96. X    if ((Filetop->linep = newline(0)) == NULL) {
  97. X        fprintf(stderr,"Unable to allocate file memory!\n");
  98. X        exit(1);
  99. X    }
  100. X    if ((Fileend->linep = newline(0)) == NULL) {
  101. X        fprintf(stderr,"Unable to allocate file memory!\n");
  102. X        exit(1);
  103. X    }
  104. X    Filemem->index = 0;
  105. X    Filetop->index = 0;
  106. X    Fileend->index = 0;
  107. X
  108. X    Filetop->linep->next = Filemem->linep;    /* connect Filetop to Filemem */
  109. X    Filemem->linep->prev = Filetop->linep;
  110. X
  111. X    Filemem->linep->next = Fileend->linep;    /* connect Filemem to Fileend */
  112. X    Fileend->linep->prev = Filemem->linep;
  113. X
  114. X    *Curschar = *Filemem;
  115. X    *Topchar  = *Filemem;
  116. X
  117. X    Filemem->linep->num = 0;
  118. X    Fileend->linep->num = 0xffff;
  119. X
  120. X    clrall();        /* clear all marks */
  121. X    u_clear();        /* clear the undo buffer */
  122. X}
  123. X
  124. X/*
  125. X * freeall() - free the current buffer
  126. X *
  127. X * Free all lines in the current buffer.
  128. X */
  129. Xvoid
  130. Xfreeall()
  131. X{
  132. X    register LINE    *lp, *xlp;
  133. X
  134. X    for (lp = Filetop->linep; lp != NULL ;lp = xlp) {
  135. X        if (lp->s != NULL)
  136. X            free(lp->s);
  137. X        xlp = lp->next;
  138. X        free((char *)lp);
  139. X    }
  140. X
  141. X    Curschar->linep = NULL;        /* clear pointers */
  142. X    Filetop->linep = NULL;
  143. X    Filemem->linep = NULL;
  144. X    Fileend->linep = NULL;
  145. X
  146. X    u_clear();
  147. X}
  148. X
  149. X/*
  150. X * bufempty() - return TRUE if the buffer is empty
  151. X */
  152. Xbool_t
  153. Xbufempty()
  154. X{
  155. X    return (buf1line() && Filemem->linep->s[0] == NUL);
  156. X}
  157. X
  158. X/*
  159. X * buf1line() - return TRUE if there is only one line
  160. X */
  161. Xbool_t
  162. Xbuf1line()
  163. X{
  164. X    return (Filemem->linep->next == Fileend->linep);
  165. X}
  166. X
  167. X/*
  168. X * lineempty() - return TRUE if the current line is empty
  169. X */
  170. Xbool_t
  171. Xlineempty()
  172. X{
  173. X    return (Curschar->linep->s[0] == NUL);
  174. X}
  175. X
  176. X/*
  177. X * endofline() - return TRUE if the given position is at end of line
  178. X *
  179. X * This routine will probably never be called with a position resting
  180. X * on the NUL byte, but handle it correctly in case it happens.
  181. X */
  182. Xbool_t
  183. Xendofline(p)
  184. Xregister LPTR    *p;
  185. X{
  186. X    return (p->linep->s[p->index] == NUL || p->linep->s[p->index+1] == NUL);
  187. X}
  188. X/*
  189. X * canincrease(n) - returns TRUE if the current line can be increased 'n' bytes
  190. X *
  191. X * This routine returns immediately if the requested space is available.
  192. X * If not, it attempts to allocate the space and adjust the data structures
  193. X * accordingly. If everything fails it returns FALSE.
  194. X */
  195. Xbool_t
  196. Xcanincrease(n)
  197. Xregister int    n;
  198. X{
  199. X    register int    nsize;
  200. X    register char    *s;        /* pointer to new space */
  201. X
  202. X    nsize = strlen(Curschar->linep->s) + 1 + n;    /* size required */
  203. X
  204. X    if (nsize <= Curschar->linep->size)
  205. X        return TRUE;
  206. X
  207. X    /*
  208. X     * Need to allocate more space for the string. Allow some extra
  209. X     * space on the assumption that we may need it soon. This avoids
  210. X     * excessive numbers of calls to malloc while entering new text.
  211. X     */
  212. X    if ((s = alloc((unsigned) (nsize + SLOP))) == NULL) {
  213. X        emsg("Can't add anything, file is too big!");
  214. X        State = NORMAL;
  215. X        return FALSE;
  216. X    }
  217. X
  218. X    Curschar->linep->size = nsize + SLOP;
  219. X    strcpy(s, Curschar->linep->s);
  220. X    free(Curschar->linep->s);
  221. X    Curschar->linep->s = s;
  222. X    
  223. X    return TRUE;
  224. X}
  225. X
  226. Xchar *
  227. Xmkstr(c)
  228. Xchar    c;
  229. X{
  230. X    static    char    s[2];
  231. X
  232. X    s[0] = c;
  233. X    s[1] = NUL;
  234. X
  235. X    return s;
  236. X}
  237. !EOR!
  238. echo extracting - cmdline.c
  239. sed 's/^X//' > cmdline.c << '!EOR!'
  240. X/* $Header: /nw/tony/src/stevie/src/RCS/cmdline.c,v 1.20 89/08/13 11:41:23 tony Exp $
  241. X *
  242. X * Routines to parse and execute "command line" commands, such as searches
  243. X * or colon commands.
  244. X */
  245. X
  246. X#include "stevie.h"
  247. X
  248. Xstatic    char    *altfile = NULL;    /* alternate file */
  249. Xstatic    int    altline;        /* line # in alternate file */
  250. X
  251. Xstatic    char    *nowrtmsg = "No write since last change (use ! to override)";
  252. Xstatic    char    *nooutfile = "No output file";
  253. Xstatic    char    *morefiles = "more files to edit";
  254. X
  255. Xextern    char    **files;        /* used for "n" and "rew" */
  256. Xextern    int    numfiles, curfile;
  257. X
  258. X#define    CMDSZ    100        /* size of the command buffer */
  259. X
  260. Xstatic    void    get_range();
  261. Xstatic    LPTR    *get_line();
  262. X
  263. X/*
  264. X * getcmdln() - read a command line from the terminal
  265. X *
  266. X * Reads a command line started by typing '/', '?', '!', or ':'. Returns a
  267. X * pointer to the string that was read. For searches, an optional trailing
  268. X * '/' or '?' is removed.
  269. X */
  270. Xchar *
  271. Xgetcmdln(firstc)
  272. Xchar    firstc;
  273. X{
  274. X    static    char    buff[CMDSZ];
  275. X    register char    *p = buff;
  276. X    register int    c;
  277. X    register char    *q;
  278. X
  279. X    gotocmd(TRUE, firstc);
  280. X
  281. X    /* collect the command string, handling '\b' and @ */
  282. X    do {
  283. X        switch (c = vgetc()) {
  284. X
  285. X        default:        /* a normal character */
  286. X            outchar(c);
  287. X            *p++ = c;
  288. X            break;
  289. X
  290. X        case BS:
  291. X            if (p > buff) {
  292. X                /*
  293. X                 * this is gross, but it relies
  294. X                 * only on 'gotocmd'
  295. X                 */
  296. X                p--;
  297. X                gotocmd(TRUE, firstc);
  298. X                for (q = buff; q < p ;q++)
  299. X                    outchar(*q);
  300. X            } else {
  301. X                msg("");
  302. X                return NULL;        /* back to cmd mode */
  303. X            }
  304. X            break;
  305. X
  306. X        case '@':            /* line kill */
  307. X            p = buff;
  308. X            gotocmd(TRUE, firstc);
  309. X            break;
  310. X
  311. X        case ESC:            /* abandon command */
  312. X            msg("");
  313. X            return  NULL;
  314. X            break;
  315. X
  316. X        case NL:            /* done reading the line */
  317. X        case CR:
  318. X            break;
  319. X        }
  320. X    } while (c != NL && c != CR);
  321. X
  322. X    *p = '\0';
  323. X
  324. X    if (firstc == '/' || firstc == '?') {    /* did we do a search? */
  325. X        /*
  326. X         * Look for a terminating '/' or '?'. This will be the first
  327. X         * one that isn't quoted. Truncate the search string there.
  328. X         */
  329. X        for (p = buff; *p ;) {
  330. X            if (*p == firstc) {    /* we're done */
  331. X                *p = '\0';
  332. X                break;
  333. X            } else if (*p == '\\')    /* next char quoted */
  334. X                p += 2;
  335. X            else
  336. X                p++;        /* normal char */
  337. X        }
  338. X    }
  339. X    return buff;
  340. X}
  341. X
  342. X/*
  343. X * docmdln() - handle a colon command
  344. X *
  345. X * Handles a colon command received interactively by getcmdln() or from
  346. X * the environment variable "EXINIT" (or eventually .virc).
  347. X */
  348. Xvoid
  349. Xdocmdln(cmdline)
  350. Xchar    *cmdline;
  351. X{
  352. X    char    buff[CMDSZ];
  353. X    char    cmdbuf[CMDSZ];
  354. X    char    argbuf[CMDSZ];
  355. X    char    *cmd, *arg;
  356. X    register char    *p;
  357. X    /*
  358. X     * The next two variables contain the bounds of any range given in a
  359. X     * command. If no range was given, both contain null line pointers.
  360. X     * If only a single line was given, u_pos will contain a null line
  361. X     * pointer.
  362. X     */
  363. X    LPTR    l_pos, u_pos;
  364. X
  365. X
  366. X    /*
  367. X     * Clear the range variables.
  368. X     */
  369. X    l_pos.linep = (struct line *) NULL;
  370. X    u_pos.linep = (struct line *) NULL;
  371. X
  372. X    if (cmdline == NULL)
  373. X        return;
  374. X
  375. X    if (strlen(cmdline) > CMDSZ-2) {
  376. X        msg("Error: command line too long");
  377. X        return;
  378. X    }
  379. X    strcpy(buff, cmdline);
  380. X
  381. X    /* skip any initial white space */
  382. X    for (cmd = buff; *cmd != NUL && isspace(*cmd) ;cmd++)
  383. X        ;
  384. X
  385. X    if (*cmd == '%') {        /* change '%' to "1,$" */
  386. X        strcpy(cmdbuf, "1,$");    /* kind of gross... */
  387. X        strcat(cmdbuf, cmd+1);
  388. X        strcpy(cmd, cmdbuf);
  389. X    }
  390. X
  391. X    while ((p=strchr(cmd, '%')) != NULL && *(p-1) != '\\') {
  392. X                    /* change '%' to Filename */
  393. X        if (Filename == NULL) {
  394. X            emsg("No filename");
  395. X            return;
  396. X        }
  397. X        *p= NUL;
  398. X        strcpy (cmdbuf, cmd);
  399. X        strcat (cmdbuf, Filename);
  400. X        strcat (cmdbuf, p+1);
  401. X        strcpy(cmd, cmdbuf);
  402. X        msg(cmd);            /*repeat */
  403. X    }
  404. X
  405. X    while ((p=strchr(cmd, '#')) != NULL && *(p-1) != '\\') {
  406. X                    /* change '#' to Altname */
  407. X        if (altfile == NULL) {
  408. X            emsg("No alternate file");
  409. X            return;
  410. X        }
  411. X        *p= NUL;
  412. X        strcpy (cmdbuf, cmd);
  413. X        strcat (cmdbuf, altfile);
  414. X        strcat (cmdbuf, p+1);
  415. X        strcpy(cmd, cmdbuf);
  416. X        msg(cmd);            /*repeat */
  417. X    }
  418. X
  419. X    /*
  420. X     * Parse a range, if present (and update the cmd pointer).
  421. X     */
  422. X    get_range(&cmd, &l_pos, &u_pos);
  423. X
  424. X    if (l_pos.linep != NULL) {
  425. X        if (LINEOF(&l_pos) > LINEOF(&u_pos)) {
  426. X            emsg("Invalid range");
  427. X            return;
  428. X        }
  429. X    }
  430. X
  431. X    strcpy(cmdbuf, cmd);    /* save the unmodified command */
  432. X
  433. X    /* isolate the command and find any argument */
  434. X    for ( p=cmd; *p != NUL && ! isspace(*p); p++ )
  435. X        ;
  436. X    if ( *p == NUL )
  437. X        arg = NULL;
  438. X    else {
  439. X        *p = NUL;
  440. X        for (p++; *p != NUL && isspace(*p) ;p++)
  441. X            ;
  442. X        if (*p == NUL)
  443. X            arg = NULL;
  444. X        else {
  445. X            strcpy(argbuf, p);
  446. X            arg = argbuf;
  447. X        }
  448. X    }
  449. X    if (strcmp(cmd,"q!") == 0)
  450. X        getout();
  451. X    if (strcmp(cmd,"q") == 0) {
  452. X        if (Changed)
  453. X            emsg(nowrtmsg);
  454. X        else {
  455. X            if ((curfile + 1) < numfiles)
  456. X                emsg(morefiles);
  457. X            else
  458. X                getout();
  459. X        }
  460. X        return;
  461. X    }
  462. X    if (strcmp(cmd,"w") == 0) {
  463. X        if (arg == NULL) {
  464. X            if (Filename != NULL) {
  465. X                writeit(Filename, &l_pos, &u_pos);
  466. X            } else
  467. X                emsg(nooutfile);
  468. X        }
  469. X        else
  470. X            writeit(arg, &l_pos, &u_pos);
  471. X        return;
  472. X    }
  473. X    if (strcmp(cmd,"wq") == 0) {
  474. X        if (Filename != NULL) {
  475. X            if (writeit(Filename, (LPTR *)NULL, (LPTR *)NULL))
  476. X                getout();
  477. X        } else
  478. X            emsg(nooutfile);
  479. X        return;
  480. X    }
  481. X    if (strcmp(cmd, "x") == 0) {
  482. X        doxit();
  483. X        return;
  484. X    }
  485. X
  486. X    if (strcmp(cmd,"f") == 0 && arg == NULL) {
  487. X        fileinfo();
  488. X        return;
  489. X    }
  490. X    if (*cmd == 'n') {
  491. X        if ((curfile + 1) < numfiles) {
  492. X            /*
  493. X             * stuff ":e[!] FILE\n"
  494. X             */
  495. X            stuffin(":e");
  496. X            if (cmd[1] == '!')
  497. X                stuffin("!");
  498. X            stuffin(" ");
  499. X            stuffin(files[++curfile]);
  500. X            stuffin("\n");
  501. X        } else
  502. X            emsg("No more files!");
  503. X        return;
  504. X    }
  505. X    if (*cmd == 'N') {
  506. X        if (curfile > 0) {
  507. X            /*
  508. X             * stuff ":e[!] FILE\n"
  509. X             */
  510. X            stuffin(":e");
  511. X            if (cmd[1] == '!')
  512. X                stuffin("!");
  513. X            stuffin(" ");
  514. X            stuffin(files[--curfile]);
  515. X            stuffin("\n");
  516. X        } else
  517. X            emsg("No more files!");
  518. X        return;
  519. X    }
  520. X    if (strncmp(cmd, "rew", 3) == 0) {
  521. X        if (numfiles <= 1)        /* nothing to rewind */
  522. X            return;
  523. X        curfile = 0;
  524. X        /*
  525. X         * stuff ":e[!] FILE\n"
  526. X         */
  527. X        stuffin(":e");
  528. X        if (cmd[3] == '!')
  529. X            stuffin("!");
  530. X        stuffin(" ");
  531. X        stuffin(files[0]);
  532. X        stuffin("\n");
  533. X        return;
  534. X    }
  535. X    if (strcmp(cmd,"e") == 0 || strcmp(cmd,"e!") == 0) {
  536. X        (void) doecmd(arg, cmd[1] == '!');
  537. X        return;
  538. X    }
  539. X    /*
  540. X     * The command ":e#" gets expanded to something like ":efile", so
  541. X     * detect that case here.
  542. X     */
  543. X    if (*cmd == 'e' && arg == NULL) {
  544. X        if (cmd[1] == '!')
  545. X            (void) doecmd(&cmd[2], TRUE);
  546. X        else
  547. X            (void) doecmd(&cmd[1], FALSE);
  548. X        return;
  549. X    }
  550. X    if (strcmp(cmd,"f") == 0) {
  551. X        EnvEval (arg, CMDSZ);    /* expand environment vars */
  552. X        Filename = strsave(arg);
  553. X        filemess("");
  554. X        return;
  555. X    }
  556. X    if (strcmp(cmd,"r") == 0) {
  557. X        if (arg == NULL) {
  558. X            badcmd();
  559. X            return;
  560. X        }
  561. X        if (readfile(arg, Curschar, 1)) {
  562. X            emsg("Can't open file");
  563. X            return;
  564. X        }
  565. X        updatescreen();
  566. X        CHANGED;
  567. X        return;
  568. X    }
  569. X    if (strcmp(cmd,"=") == 0) {
  570. X        smsg("%d", cntllines(Filemem, &l_pos));
  571. X        return;
  572. X    }
  573. X    if (strncmp(cmd,"ta", 2) == 0) {
  574. X        dotag(arg, cmd[2] == '!');
  575. X        return;
  576. X    }
  577. X    if (strncmp(cmd,"untag", 5) == 0) {
  578. X        if (P(P_TG))
  579. X            dountag(cmd[5]);
  580. X        else
  581. X            emsg("Tag stacking not enabled");
  582. X        return;
  583. X    }
  584. X    if (strncmp(cmd,"set", 2) == 0) {
  585. X        doset(arg);
  586. X        return;
  587. X    }
  588. X    if (strcmp(cmd,"help") == 0) {
  589. X        if (help()) {
  590. X            screenclear();
  591. X            updatescreen();
  592. X        }
  593. X        return;
  594. X    }
  595. X    if (strncmp(cmd, "ve", 2) == 0) {
  596. X        extern    char    *Version;
  597. X
  598. X        msg(Version);
  599. X        return;
  600. X    }
  601. X    if (strcmp(cmd, "sh") == 0) {
  602. X        doshell(NULL);
  603. X        return;
  604. X    }
  605. X    if (*cmd == '!') {
  606. X        doshell(cmdbuf+1);
  607. X        return;
  608. X    }
  609. X    if (strncmp(cmd, "s/", 2) == 0) {
  610. X        dosub(&l_pos, &u_pos, cmdbuf+1);
  611. X        return;
  612. X    }
  613. X    if (strncmp(cmd, "g/", 2) == 0) {
  614. X        doglob(&l_pos, &u_pos, cmdbuf+1);
  615. X        return;
  616. X    }
  617. X    /*
  618. X     * If we got a line, but no command, then go to the line.
  619. X     */
  620. X    if (*cmd == NUL && l_pos.linep != NULL) {
  621. X        *Curschar = l_pos;
  622. X        return;
  623. X    }
  624. X
  625. X    badcmd();
  626. X}
  627. X
  628. X
  629. Xdoxit()
  630. X{
  631. X    if (Changed) {
  632. X        if (Filename != NULL) {
  633. X            if (!writeit(Filename, (LPTR *)NULL, (LPTR *)NULL))
  634. X                return;
  635. X        } else {
  636. X            emsg(nooutfile);
  637. X            return;
  638. X        }
  639. X    }
  640. X    if ((curfile + 1) < numfiles)
  641. X        emsg(morefiles);
  642. X    else
  643. X        getout();
  644. X}
  645. X
  646. X/*
  647. X * get_range - parse a range specifier
  648. X *
  649. X * Ranges are of the form:
  650. X *
  651. X * addr[,addr]
  652. X *
  653. X * where 'addr' is:
  654. X *
  655. X * $  [+- NUM]
  656. X * 'x [+- NUM]    (where x denotes a currently defined mark)
  657. X * .  [+- NUM]
  658. X * NUM
  659. X *
  660. X * The pointer *cp is updated to point to the first character following
  661. X * the range spec. If an initial address is found, but no second, the
  662. X * upper bound is equal to the lower.
  663. X */
  664. Xstatic void
  665. Xget_range(cp, lower, upper)
  666. Xregister char    **cp;
  667. XLPTR    *lower, *upper;
  668. X{
  669. X    register LPTR    *l;
  670. X    register char    *p;
  671. X
  672. X    if ((l = get_line(cp)) == NULL)
  673. X        return;
  674. X
  675. X    *lower = *l;
  676. X
  677. X    for (p = *cp; *p != NUL && isspace(*p) ;p++)
  678. X        ;
  679. X
  680. X    *cp = p;
  681. X
  682. X    if (*p != ',') {        /* is there another line spec ? */
  683. X        *upper = *lower;
  684. X        return;
  685. X    }
  686. X
  687. X    *cp = ++p;
  688. X
  689. X    if ((l = get_line(cp)) == NULL) {
  690. X        *upper = *lower;
  691. X        return;
  692. X    }
  693. X
  694. X    *upper = *l;
  695. X}
  696. X
  697. Xstatic LPTR *
  698. Xget_line(cp)
  699. Xchar    **cp;
  700. X{
  701. X    static    LPTR    pos;
  702. X    LPTR    *lp;
  703. X    register char    *p, c;
  704. X    register int    lnum;
  705. X
  706. X    pos.index = 0;        /* shouldn't matter... check back later */
  707. X
  708. X    p = *cp;
  709. X    /*
  710. X     * Determine the basic form, if present.
  711. X     */
  712. X    switch (c = *p++) {
  713. X
  714. X    case '$':
  715. X        pos.linep = Fileend->linep->prev;
  716. X        break;
  717. X
  718. X    case '.':
  719. X        pos.linep = Curschar->linep;
  720. X        break;
  721. X
  722. X    case '\'':
  723. X        if ((lp = getmark(*p++)) == NULL) {
  724. X            emsg("Unknown mark");
  725. X            return (LPTR *) NULL;
  726. X        }
  727. X        pos = *lp;
  728. X        break;
  729. X
  730. X    case '0': case '1': case '2': case '3': case '4':
  731. X    case '5': case '6': case '7': case '8': case '9':
  732. X        for (lnum = c - '0'; isdigit(*p) ;p++)
  733. X            lnum = (lnum * 10) + (*p - '0');
  734. X
  735. X        pos = *gotoline(lnum);
  736. X        break;
  737. X
  738. X    default:
  739. X        return (LPTR *) NULL;
  740. X    }
  741. X
  742. X    while (*p != NUL && isspace(*p))
  743. X        p++;
  744. X
  745. X    if (*p == '-' || *p == '+') {
  746. X        bool_t    neg = (*p++ == '-');
  747. X
  748. X        for (lnum = 0; isdigit(*p) ;p++)
  749. X            lnum = (lnum * 10) + (*p - '0');
  750. X
  751. X        if (neg)
  752. X            lnum = -lnum;
  753. X
  754. X        pos = *gotoline( cntllines(Filemem, &pos) + lnum );
  755. X    }
  756. X
  757. X    *cp = p;
  758. X    return &pos;
  759. X}
  760. X
  761. Xvoid
  762. Xbadcmd()
  763. X{
  764. X    emsg("Unrecognized command");
  765. X}
  766. X
  767. Xbool_t
  768. Xdoecmd(arg, force)
  769. Xchar    *arg;
  770. Xbool_t    force;
  771. X{
  772. X    int    line = 1;        /* line # to go to in new file */
  773. X
  774. X    if (!force && Changed) {
  775. X        emsg(nowrtmsg);
  776. X        if (altfile)
  777. X            free(altfile);
  778. X        altfile = strsave(arg);
  779. X        return FALSE;
  780. X    }
  781. X    if (arg != NULL) {
  782. X        /*
  783. X         * First detect a ":e" on the current file. This is mainly
  784. X         * for ":ta" commands where the destination is within the
  785. X         * current file.
  786. X         */
  787. X        if (Filename != NULL && strcmp(arg, Filename) == 0) {
  788. X            if (!Changed || (Changed && !force))
  789. X                return TRUE;
  790. X        }
  791. X        if (altfile) {
  792. X            if (strcmp (arg, altfile) == 0)
  793. X                line = altline;
  794. X            free(altfile);
  795. X        }
  796. X        altfile = Filename;
  797. X        altline = cntllines(Filemem, Curschar);
  798. X        Filename = strsave(arg);
  799. X    }
  800. X    if (Filename == NULL) {
  801. X        emsg("No filename");
  802. X        return FALSE;
  803. X    }
  804. X
  805. X    /* clear mem and read file */
  806. X    freeall();
  807. X    filealloc();
  808. X    UNCHANGED;
  809. X
  810. X    if (readfile(Filename, Filemem, 0))
  811. X        filemess("[New File]");
  812. X
  813. X    *Topchar = *Curschar;
  814. X    if (line != 1) {
  815. X        stuffnum(line);
  816. X        stuffin("G");
  817. X    }
  818. X    do_mlines();
  819. X    setpcmark();
  820. X    updatescreen();
  821. X    return TRUE;
  822. X}
  823. X
  824. Xvoid
  825. Xgotocmd(clr, firstc)
  826. Xbool_t  clr;
  827. Xchar    firstc;
  828. X{
  829. X    windgoto(Rows-1,0);
  830. X    if (clr)
  831. X        CLEOL;        /* clear the bottom line */
  832. X    if (firstc)
  833. X        outchar(firstc);
  834. X}
  835. X
  836. X/*
  837. X * msg(s) - displays the string 's' on the status line
  838. X */
  839. Xvoid
  840. Xmsg(s)
  841. Xchar    *s;
  842. X{
  843. X    gotocmd(TRUE, 0);
  844. X    outstr(s);
  845. X    flushbuf();
  846. X}
  847. X
  848. X/*VARARGS1*/
  849. Xvoid
  850. Xsmsg(s, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16)
  851. Xchar    *s;
  852. Xint    a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16;
  853. X{
  854. X    char    sbuf[80];
  855. X
  856. X    sprintf(sbuf, s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16);
  857. X    msg(sbuf);
  858. X}
  859. X
  860. X/*
  861. X * emsg() - display an error message
  862. X *
  863. X * Rings the bell, if appropriate, and calls message() to do the real work
  864. X */
  865. Xvoid
  866. Xemsg(s)
  867. Xchar    *s;
  868. X{
  869. X    if (P(P_EB))
  870. X        beep();
  871. X    msg(s);
  872. X}
  873. X
  874. Xvoid
  875. Xwait_return()
  876. X{
  877. X    register char    c;
  878. X
  879. X    if (got_int)
  880. X        outstr("Interrupt: ");
  881. X
  882. X    outstr("Press RETURN to continue");
  883. X    do {
  884. X        c = vgetc();
  885. X    } while (c != CR && c != NL && c != ' ' && c != ':');
  886. X
  887. X    if (c == ':') {
  888. X        outchar(NL);
  889. X        docmdln(getcmdln(c));
  890. X    } else
  891. X        screenclear();
  892. X
  893. X    updatescreen();
  894. X}
  895. !EOR!
  896. echo extracting - edit.c
  897. sed 's/^X//' > edit.c << '!EOR!'
  898. X/* $Header: /nw/tony/src/stevie/src/RCS/edit.c,v 1.11 89/08/02 19:57:12 tony Exp $
  899. X *
  900. X * The main edit loop as well as some other simple cursor movement routines.
  901. X */
  902. X
  903. X#include "stevie.h"
  904. X
  905. X/*
  906. X * This flag is used to make auto-indent work right on lines where only
  907. X * a <RETURN> or <ESC> is typed. It is set when an auto-indent is done,
  908. X * and reset when any other editting is done on the line. If an <ESC>
  909. X * or <RETURN> is received, and did_ai is TRUE, the line is truncated.
  910. X */
  911. Xbool_t    did_ai = FALSE;
  912. X
  913. Xvoid
  914. Xedit()
  915. X{
  916. X    extern    bool_t    need_redraw;
  917. X    int    c;
  918. X    register char    *p, *q;
  919. X
  920. X    Prenum = 0;
  921. X
  922. X    /* position the display and the cursor at the top of the file. */
  923. X    *Topchar = *Filemem;
  924. X    *Curschar = *Filemem;
  925. X    Cursrow = Curscol = 0;
  926. X
  927. X    do_mlines();        /* check for mode lines before starting */
  928. X
  929. X    updatescreen();
  930. X
  931. X    for ( ;; ) {
  932. X
  933. X    /* Figure out where the cursor is based on Curschar. */
  934. X    cursupdate();
  935. X
  936. X    if (need_redraw && !anyinput()) {
  937. X        updatescreen();
  938. X        need_redraw = FALSE;
  939. X    }
  940. X
  941. X    if (!anyinput())
  942. X        windgoto(Cursrow,Curscol);
  943. X
  944. X
  945. X    c = vgetc();
  946. X
  947. X    if (State == NORMAL) {
  948. X
  949. X        /* We're in the normal (non-insert) mode. */
  950. X
  951. X        /* Pick up any leading digits and compute 'Prenum' */
  952. X        if ( (Prenum>0 && isdigit(c)) || (isdigit(c) && c!='0') ){
  953. X            Prenum = Prenum*10 + (c-'0');
  954. X            continue;
  955. X        }
  956. X        /* execute the command */
  957. X        normal(c);
  958. X        Prenum = 0;
  959. X
  960. X    } else {
  961. X
  962. X        /*
  963. X         * Insert or Replace mode.
  964. X         */
  965. X        switch (c) {
  966. X
  967. X        case ESC:    /* an escape ends input mode */
  968. X
  969. X            /*
  970. X             * If we just did an auto-indent, truncate the
  971. X             * line, and put the cursor back.
  972. X             */
  973. X            if (did_ai) {
  974. X                Curschar->linep->s[0] = NUL;
  975. X                Curschar->index = 0;
  976. X                did_ai = FALSE;
  977. X            }
  978. X
  979. X            set_want_col = TRUE;
  980. X
  981. X            /* Don't end up on a '\n' if you can help it. */
  982. X            if (gchar(Curschar) == NUL && Curschar->index != 0)
  983. X                dec(Curschar);
  984. X
  985. X            /*
  986. X             * The cursor should end up on the last inserted
  987. X             * character. This is an attempt to match the real
  988. X             * 'vi', but it may not be quite right yet.
  989. X             */
  990. X            if (Curschar->index != 0 && !endofline(Curschar))
  991. X                dec(Curschar);
  992. X
  993. X            State = NORMAL;
  994. X            msg("");
  995. X
  996. X            /* construct the Redo buffer */
  997. X            p=Redobuff;
  998. X            q=Insbuff;
  999. X            while ( q < Insptr )
  1000. X                *p++ = *q++;
  1001. X            *p++ = ESC;
  1002. X            *p = NUL;
  1003. X            updatescreen();
  1004. X            break;
  1005. X
  1006. X        case CTRL('D'):
  1007. X            /*
  1008. X             * Control-D is treated as a backspace in insert
  1009. X             * mode to make auto-indent easier. This isn't
  1010. X             * completely compatible with vi, but it's a lot
  1011. X             * easier than doing it exactly right, and the
  1012. X             * difference isn't very noticeable.
  1013. X             */
  1014. X        case BS:
  1015. X            /* can't backup past starting point */
  1016. X            if (Curschar->linep == Insstart->linep &&
  1017. X                Curschar->index <= Insstart->index) {
  1018. X                beep();
  1019. X                break;
  1020. X            }
  1021. X
  1022. X            /* can't backup to a previous line */
  1023. X            if (Curschar->linep != Insstart->linep &&
  1024. X                Curschar->index <= 0) {
  1025. X                beep();
  1026. X                break;
  1027. X            }
  1028. X
  1029. X            did_ai = FALSE;
  1030. X            dec(Curschar);
  1031. X            if (State == INSERT)
  1032. X                delchar(TRUE);
  1033. X            /*
  1034. X             * It's a little strange to put backspaces into
  1035. X             * the redo buffer, but it makes auto-indent a
  1036. X             * lot easier to deal with.
  1037. X             */
  1038. X            *Insptr++ = BS;
  1039. X            Ninsert++;
  1040. X            cursupdate();
  1041. X            updateline();
  1042. X            break;
  1043. X
  1044. X        case CR:
  1045. X        case NL:
  1046. X            if (State == REPLACE)        /* DMT added, 12/89 */
  1047. X                delchar(FALSE);
  1048. X            *Insptr++ = NL;
  1049. X            Ninsert++;
  1050. X            opencmd(FORWARD, TRUE);        /* open a new line */
  1051. X            break;
  1052. X
  1053. X        default:
  1054. X            did_ai = FALSE;
  1055. X            insertchar(c);
  1056. X            break;
  1057. X        }
  1058. X    }
  1059. X    }
  1060. X}
  1061. X
  1062. Xvoid
  1063. Xinsertchar(c)
  1064. Xint    c;
  1065. X{
  1066. X    inschar(c);
  1067. X    *Insptr++ = c;
  1068. X    Ninsert++;
  1069. X    /*
  1070. X     * The following kludge avoids overflowing the statically
  1071. X     * allocated insert buffer. Just dump the user back into
  1072. X     * command mode, and print a message.
  1073. X     */
  1074. X    if (Insptr+10 >= &Insbuff[1024]) {
  1075. X        stuffin(mkstr(ESC));
  1076. X        emsg("No buffer space - returning to command mode");
  1077. X        sleep(2);
  1078. X    }
  1079. X    updateline();
  1080. X}
  1081. X
  1082. Xvoid
  1083. Xgetout()
  1084. X{
  1085. X    windgoto(Rows-1,0);
  1086. X    putchar('\r');
  1087. X    putchar('\n');
  1088. X    windexit(0);
  1089. X}
  1090. X
  1091. Xvoid
  1092. Xscrolldown(nlines)
  1093. Xint    nlines;
  1094. X{
  1095. X    register LPTR    *p;
  1096. X    register int    done = 0;    /* total # of physical lines done */
  1097. X
  1098. X    /* Scroll up 'nlines' lines. */
  1099. X    while (nlines--) {
  1100. X        if ((p = prevline(Topchar)) == NULL)
  1101. X            break;
  1102. X        done += plines(p);
  1103. X        *Topchar = *p;
  1104. X        /*
  1105. X         * If the cursor is on the bottom line, we need to
  1106. X         * make sure it gets moved up the appropriate number
  1107. X         * of lines so it stays on the screen.
  1108. X         */
  1109. X        if (Curschar->linep == Botchar->linep->prev) {
  1110. X            int    i = 0;
  1111. X            while (i < done) {
  1112. X                i += plines(Curschar);
  1113. X                *Curschar = *prevline(Curschar);
  1114. X            }
  1115. X        }
  1116. X    }
  1117. X    s_ins(0, done);
  1118. X}
  1119. X
  1120. Xvoid
  1121. Xscrollup(nlines)
  1122. Xint    nlines;
  1123. X{
  1124. X    register LPTR    *p;
  1125. X    register int    done = 0;    /* total # of physical lines done */
  1126. X    register int    pl;        /* # of plines for the current line */
  1127. X
  1128. X    /* Scroll down 'nlines' lines. */
  1129. X    while (nlines--) {
  1130. X        pl = plines(Topchar);
  1131. X        if ((p = nextline(Topchar)) == NULL)
  1132. X            break;
  1133. X        done += pl;
  1134. X        if (Curschar->linep == Topchar->linep)
  1135. X            *Curschar = *p;
  1136. X        *Topchar = *p;
  1137. X
  1138. X    }
  1139. X    s_del(0, done);
  1140. X}
  1141. X
  1142. X/*
  1143. X * oneright
  1144. X * oneleft
  1145. X * onedown
  1146. X * oneup
  1147. X *
  1148. X * Move one char {right,left,down,up}.  Return TRUE when
  1149. X * sucessful, FALSE when we hit a boundary (of a line, or the file).
  1150. X */
  1151. X
  1152. Xbool_t
  1153. Xoneright()
  1154. X{
  1155. X    set_want_col = TRUE;
  1156. X
  1157. X    switch (inc(Curschar)) {
  1158. X
  1159. X    case 0:
  1160. X        return TRUE;
  1161. X
  1162. X    case 1:
  1163. X        dec(Curschar);        /* crossed a line, so back up */
  1164. X        /* fall through */
  1165. X    case -1:
  1166. X        return FALSE;
  1167. X    }
  1168. X    /*NOTREACHED*/
  1169. X}
  1170. X
  1171. Xbool_t
  1172. Xoneleft()
  1173. X{
  1174. X    set_want_col = TRUE;
  1175. X
  1176. X    switch (dec(Curschar)) {
  1177. X
  1178. X    case 0:
  1179. X        return TRUE;
  1180. X
  1181. X    case 1:
  1182. X        inc(Curschar);        /* crossed a line, so back up */
  1183. X        /* fall through */
  1184. X    case -1:
  1185. X        return FALSE;
  1186. X    }
  1187. X    /*NOTREACHED*/
  1188. X}
  1189. X
  1190. Xvoid
  1191. Xbeginline(flag)
  1192. Xbool_t    flag;
  1193. X{
  1194. X    while ( oneleft() )
  1195. X        ;
  1196. X    if (flag) {
  1197. X        while (isspace(gchar(Curschar)) && oneright())
  1198. X            ;
  1199. X    }
  1200. X    set_want_col = TRUE;
  1201. X}
  1202. X
  1203. Xbool_t
  1204. Xoneup(n)
  1205. Xint    n;
  1206. X{
  1207. X    LPTR    p, *np;
  1208. X    register int    k;
  1209. X
  1210. X    p = *Curschar;
  1211. X    for ( k=0; k<n; k++ ) {
  1212. X        /* Look for the previous line */
  1213. X        if ( (np=prevline(&p)) == NULL ) {
  1214. X            /* If we've at least backed up a little .. */
  1215. X            if ( k > 0 )
  1216. X                break;    /* to update the cursor, etc. */
  1217. X            else
  1218. X                return FALSE;
  1219. X        }
  1220. X        p = *np;
  1221. X    }
  1222. X    *Curschar = p;
  1223. X    /* This makes sure Topchar gets updated so the complete line */
  1224. X    /* is one the screen. */
  1225. X    cursupdate();
  1226. X    /* try to advance to the column we want to be at */
  1227. X    *Curschar = *coladvance(&p, Curswant);
  1228. X    return TRUE;
  1229. X}
  1230. X
  1231. Xbool_t
  1232. Xonedown(n)
  1233. Xint    n;
  1234. X{
  1235. X    LPTR    p, *np;
  1236. X    register int    k;
  1237. X
  1238. X    p = *Curschar;
  1239. X    for ( k=0; k<n; k++ ) {
  1240. X        /* Look for the next line */
  1241. X        if ( (np=nextline(&p)) == NULL ) {
  1242. X            if ( k > 0 )
  1243. X                break;
  1244. X            else
  1245. X                return FALSE;
  1246. X        }
  1247. X        p = *np;
  1248. X    }
  1249. X    /* try to advance to the column we want to be at */
  1250. X    *Curschar = *coladvance(&p, Curswant);
  1251. X    return TRUE;
  1252. X}
  1253. !EOR!
  1254. echo extracting - enveval.c
  1255. sed 's/^X//' > enveval.c << '!EOR!'
  1256. X/*
  1257. X *    Evaluate a string, expanding environment variables
  1258. X *    where encountered.
  1259. X *    We'll use the UNIX convention for representing environment
  1260. X *    variables: $xxx, where xxx is the shortest string that
  1261. X *    matches some environment variable.
  1262. X */
  1263. X
  1264. X#include <stdio.h>
  1265. X#include <string.h>
  1266. X
  1267. Xchar    *getenv();
  1268. X
  1269. Xint
  1270. XEnvEval (s, len)
  1271. X  char *s;
  1272. X  int   len;
  1273. X/*------------------------------------------------------------------
  1274. X *  s=    Pointer to buffer, currently containing string.  It will be
  1275. X *    expanded in-place in the buffer.
  1276. X *  len=Maximum allowable length of the buffer.  (In this version, we
  1277. X *    use a static buffer of 256 bytes internally.)
  1278. X *
  1279. X * RETURNS:
  1280. X *     0    on success.
  1281. X *    -1    on failure.  In this case, s may contain a partially
  1282. X *            converted string, but it won't contain a partial
  1283. X *            string.  It will be the FULL string, with as
  1284. X *            many substitutions as we could find.
  1285. X */
  1286. X
  1287. X{
  1288. X#define    LEN    256
  1289. X    char    buf [LEN];
  1290. X    char    *s1, *s2;
  1291. X    char    *b1;
  1292. X    int    done=0;
  1293. X
  1294. X    if (len > LEN)
  1295. X        return (-1);
  1296. X
  1297. X    s1 = s;
  1298. X
  1299. X    /*  Check for '$', and expand when we find one.  */
  1300. X    while (!done) {
  1301. X        if ((s1 = strchr (s1, '$')) == NULL)
  1302. X            done = 1;
  1303. X        else {
  1304. X            /*
  1305. X             *  Here's where the real work gets done.
  1306. X             *  We'll find the env.var., and convert
  1307. X             *  it into buf, then copy back into s
  1308. X             *  and continue.
  1309. X             */
  1310. X            char    c;
  1311. X            int    need, got;
  1312. X
  1313. X            /* Test successively longer strings, to see
  1314. X             * if they're env.vars.
  1315. X             */
  1316. X            for (s2=++s1+1;    ; s2++) {
  1317. X                c = *s2;    /* save it */
  1318. X                *s2 = '\0';
  1319. X                b1 = getenv (s1);
  1320. X                *s2 = c;        /* restore it */
  1321. X                if (b1)         /* found it */
  1322. X                    break;
  1323. X                if (!*s2)        /* nothing to try */
  1324. X                    goto Failed;
  1325. X            }
  1326. X            --s1;    /* Back to the '$' */
  1327. X
  1328. X            /* OK, we've found one (between s1 & s2,
  1329. X             * non-inclusive).  Its value is in b1.
  1330. X             * Do the substitution into bufp,
  1331. X             * and copy back into s.
  1332. X             */
  1333. X            need = strlen(b1) + strlen(s2) + 1;
  1334. X            got  = len - (s1-s);
  1335. X            if (need > got)
  1336. X                goto Failed;
  1337. X            strcpy (buf, b1);
  1338. X            strcat (buf, s2);
  1339. X            strcpy (s1, buf);
  1340. X        }
  1341. X    }
  1342. X
  1343. X    /*  If we get here, the converted value is in s  */
  1344. X    return (0);
  1345. X
  1346. X   Failed:
  1347. X    return (-1);
  1348. X}
  1349. X
  1350. X
  1351. X/* #define SAMPLE */
  1352. X#ifdef SAMPLE  /***************************************************/
  1353. X
  1354. Xmain (int argc, char **argv)
  1355. X{
  1356. X    int    i, ret;
  1357. X
  1358. X    for (i=1; i<argc; i++) {
  1359. X        printf ("Convert  %s  to", argv [i]);
  1360. X        ret = EnvEval (argv [i], 80);
  1361. X        printf ("  %s", argv [i]);
  1362. X        if (ret)
  1363. X            printf ("  -  Failed");
  1364. X        putchar ('\n');
  1365. X    }
  1366. X}
  1367. X
  1368. X#endif
  1369. !EOR!
  1370. echo extracting - fileio.c
  1371. sed 's/^X//' > fileio.c << '!EOR!'
  1372. X/* $Header: /nw/tony/src/stevie/src/RCS/fileio.c,v 1.12 89/08/06 09:50:01 tony Exp $
  1373. X *
  1374. X * Basic file I/O routines.
  1375. X */
  1376. X
  1377. X#include <sys/types.h>        /* For stat() and chmod() */
  1378. X#include <sys/stat.h>        /* Ditto */
  1379. X#include "stevie.h"
  1380. X
  1381. Xvoid
  1382. Xfilemess(s)
  1383. Xchar    *s;
  1384. X{
  1385. X    smsg("\"%s\" %s", (Filename == NULL) ? "" : Filename, s);
  1386. X    flushbuf();
  1387. X}
  1388. X
  1389. Xvoid
  1390. Xrenum()
  1391. X{
  1392. X    LPTR    *p;
  1393. X    unsigned long l = 0;
  1394. X
  1395. X    for (p = Filemem; p != NULL ;p = nextline(p), l += LINEINC)
  1396. X        p->linep->num = l;
  1397. X
  1398. X    Fileend->linep->num = 0xffffffff;
  1399. X}
  1400. X
  1401. X#define    MAXLINE    256    /* maximum size of a line */
  1402. X
  1403. Xbool_t
  1404. Xreadfile(fname,fromp,nochangename)
  1405. X/*-------------------------------------------------
  1406. X * Note that this will try to expand the file name using environment
  1407. X * variables.  For this reason, we copy it into an 80-byte buffer,
  1408. X * so that there's room to expand it.
  1409. X *
  1410. X * It uses the environment-variable convention of UNIX, even
  1411. X * under systems with other conventions.  That is, your home directory
  1412. X * would be called $HOME (even in DOS, where you might want to say %HOME%)
  1413. X *-----------------------------------------------------*/
  1414. Xchar    *fname;
  1415. XLPTR    *fromp;
  1416. Xbool_t    nochangename;    /* if TRUE, don't change the Filename */
  1417. X{
  1418. X    FILE    *f, *fopen();
  1419. X    register LINE    *curr;
  1420. X    char    buff[MAXLINE], buf2[80];
  1421. X    char    namebuf[80];
  1422. X    register int    i, c;
  1423. X    register long    nchars = 0;
  1424. X    int    linecnt = 0;
  1425. X    bool_t    wasempty = bufempty();
  1426. X    int    nonascii = 0;        /* count garbage characters */
  1427. X    int    nulls = 0;        /* count nulls */
  1428. X    bool_t    incomplete = FALSE;    /* was the last line incomplete? */
  1429. X    bool_t    toolong = FALSE;    /* a line was too long */
  1430. X
  1431. X    curr = fromp->linep;
  1432. X
  1433. X    strncpy (namebuf, fname, 80);
  1434. X    EnvEval (namebuf, 80);
  1435. X
  1436. X    if ( ! nochangename )
  1437. X        Filename = strsave(namebuf);
  1438. X
  1439. X    if ( (f=fopen(fixname(namebuf),"r")) == NULL )
  1440. X        return TRUE;
  1441. X
  1442. X    filemess("");
  1443. X
  1444. X    i = 0;
  1445. X    do {
  1446. X        c = getc(f);
  1447. X
  1448. X        if (c == EOF) {
  1449. X            if (i == 0)    /* normal loop termination */
  1450. X                break;
  1451. X
  1452. X            /*
  1453. X             * If we get EOF in the middle of a line, note the
  1454. X             * fact and complete the line ourselves.
  1455. X             */
  1456. X            incomplete = TRUE;
  1457. X            c = NL;
  1458. X        }
  1459. X
  1460. X        /*
  1461. X         * Abort if we get an interrupt, but finished reading the
  1462. X         * current line first.
  1463. X         */
  1464. X        if (got_int && i == 0)
  1465. X            break;
  1466. X
  1467. X        if (c >= 0x80) {
  1468. X            c -= 0x80;
  1469. X            nonascii++;
  1470. X        }
  1471. X
  1472. X        /*
  1473. X         * If we reached the end of the line, OR we ran out of
  1474. X         * space for it, then process the complete line.
  1475. X         */
  1476. X        if (c == NL || i == (MAXLINE-1)) {
  1477. X            LINE    *lp;
  1478. X
  1479. X            if (c != NL)
  1480. X                toolong = TRUE;
  1481. X
  1482. X            buff[i] = '\0';
  1483. X            if ((lp = newline(strlen(buff))) == NULL)
  1484. X                exit(1);
  1485. X
  1486. X            strcpy(lp->s, buff);
  1487. X
  1488. X            curr->next->prev = lp;    /* new line to next one */
  1489. X            lp->next = curr->next;
  1490. X
  1491. X            curr->next = lp;    /* new line to prior one */
  1492. X            lp->prev = curr;
  1493. X
  1494. X            curr = lp;        /* new line becomes current */
  1495. X            i = 0;
  1496. X            linecnt++;
  1497. X
  1498. X        } else if (c == NUL)
  1499. X            nulls++;        /* count and ignore nulls */
  1500. X        else {
  1501. X            buff[i++] = c;        /* normal character */
  1502. X        }
  1503. X
  1504. X        nchars++;
  1505. X
  1506. X    } while (!incomplete && !toolong);
  1507. X
  1508. X    fclose(f);
  1509. X
  1510. X    /*
  1511. X     * If the buffer was empty when we started, we have to go back
  1512. X     * and remove the "dummy" line at Filemem and patch up the ptrs.
  1513. X     */
  1514. X    if (wasempty && nchars != 0) {
  1515. X        LINE    *dummy = Filemem->linep;    /* dummy line ptr */
  1516. X
  1517. X        free(dummy->s);                /* free string space */
  1518. X        Filemem->linep = Filemem->linep->next;
  1519. X        free((char *)dummy);            /* free LINE struct */
  1520. X        Filemem->linep->prev = Filetop->linep;
  1521. X        Filetop->linep->next = Filemem->linep;
  1522. X
  1523. X        Curschar->linep = Filemem->linep;
  1524. X        Topchar->linep  = Filemem->linep;
  1525. X    }
  1526. X
  1527. X    renum();
  1528. X
  1529. X    if (got_int) {
  1530. X        smsg("\"%s\" Interrupt", namebuf);
  1531. X        got_int = FALSE;
  1532. X        return FALSE;        /* an interrupt isn't really an error */
  1533. X    }
  1534. X
  1535. X    if (toolong) {
  1536. X        smsg("\"%s\" Line too long", namebuf);
  1537. X        return FALSE;
  1538. X    }
  1539. X
  1540. X    sprintf(buff, "\"%s\" %s%d line%s, %ld character%s",
  1541. X        namebuf,
  1542. X        incomplete ? "[Incomplete last line] " : "",
  1543. X        linecnt, (linecnt != 1) ? "s" : "",
  1544. X        nchars, (nchars != 1) ? "s" : "");
  1545. X
  1546. X    buf2[0] = NUL;
  1547. X
  1548. X    if (nonascii || nulls) {
  1549. X        if (nonascii) {
  1550. X            if (nulls)
  1551. X                sprintf(buf2, " (%d null, %d non-ASCII)",
  1552. X                    nulls, nonascii);
  1553. X            else
  1554. X                sprintf(buf2, " (%d non-ASCII)", nonascii);
  1555. X        } else
  1556. X            sprintf(buf2, " (%d null)", nulls);
  1557. X    }
  1558. X    strcat(buff, buf2);
  1559. X    msg(buff);
  1560. X
  1561. X    return FALSE;
  1562. X}
  1563. X
  1564. X
  1565. X/*
  1566. X * writeit - write to file 'fname' lines 'start' through 'end'
  1567. X *
  1568. X * If either 'start' or 'end' contain null line pointers, the default
  1569. X * is to use the start or end of the file respectively.
  1570. X */
  1571. Xbool_t
  1572. Xwriteit(fname, start, end)
  1573. Xchar    *fname;
  1574. XLPTR    *start, *end;
  1575. X{
  1576. X    FILE    *f, *fopen();
  1577. X    FILE    *fopenb();        /* open in binary mode, where needed */
  1578. X    char    *backup;
  1579. X    register char    *s;
  1580. X    register long    nchars;
  1581. X    register int    lines;
  1582. X    register LPTR    *p;
  1583. X    struct stat statbuf;
  1584. X    int        statres;
  1585. X
  1586. X    smsg("\"%s\"", fname);
  1587. X
  1588. X    /* Expand any environment variables left in the name.
  1589. X     * fname better be in a variable big enough to handle the
  1590. X     * expansion (80 bytes).
  1591. X     */
  1592. X    EnvEval (fname, 80);
  1593. X
  1594. X    /* If the file already exists, get what we need to know
  1595. X     * (like current mode).
  1596. X     */
  1597. X    statres = stat (fname, &statbuf);
  1598. X
  1599. X    /*
  1600. X     * Form the backup file name - change foo.* to foo.bak
  1601. X     */
  1602. X    backup = alloc((unsigned) (strlen(fname) + 5));
  1603. X    if (backup == NULL) {
  1604. X        emsg("Can't open file for writing!");
  1605. X        return FALSE;
  1606. X    }
  1607. X
  1608. X    strcpy(backup, fname);
  1609. X    for (s = backup; *s && *s != '.' ;s++)
  1610. X        ;
  1611. X    *s = NUL;
  1612. X    strcat(backup, ".bak");
  1613. X
  1614. X    /*
  1615. X     * Delete any existing backup and move the current version
  1616. X     * to the backup. For safety, we don't remove the backup
  1617. X     * until the write has finished successfully. And if the
  1618. X     * 'backup' option is set, leave it around.
  1619. X     */
  1620. X    rename(fname, backup);
  1621. X
  1622. X
  1623. X    f = P(P_CR) ? fopen(fixname(fname), "w") : fopenb(fixname(fname), "w");
  1624. X
  1625. X    if (f == NULL) {
  1626. X        emsg("Can't open file for writing!");
  1627. X        free(backup);
  1628. X        return FALSE;
  1629. X    }
  1630. X
  1631. X    /*
  1632. X     * If we were given a bound, start there. Otherwise just
  1633. X     * start at the beginning of the file.
  1634. X     */
  1635. X    if (start == NULL || start->linep == NULL)
  1636. X        p = Filemem;
  1637. X    else
  1638. X        p = start;
  1639. X
  1640. X    lines = nchars = 0;
  1641. X    do {
  1642. X        fprintf(f, "%s\n", p->linep->s);
  1643. X        nchars += strlen(p->linep->s) + 1;
  1644. X        lines++;
  1645. X
  1646. X        /*
  1647. X         * If we were given an upper bound, and we just did that
  1648. X         * line, then bag it now.
  1649. X         */
  1650. X        if (end != NULL && end->linep != NULL) {
  1651. X            if (end->linep == p->linep)
  1652. X                break;
  1653. X        }
  1654. X
  1655. X    } while ((p = nextline(p)) != NULL);
  1656. X
  1657. X    fclose(f);
  1658. X    smsg("\"%s\" %d line%s, %ld character%s", fname,
  1659. X        lines, (lines > 1) ? "s" : "",
  1660. X        nchars, (nchars > 1) ? "s" : "");
  1661. X
  1662. X    UNCHANGED;
  1663. X
  1664. X    /*
  1665. X     * Remove the backup unless they want it left around
  1666. X     */
  1667. X    if (!P(P_BK))
  1668. X        remove(backup);
  1669. X
  1670. X    free(backup);
  1671. X
  1672. X    /*
  1673. X     * Set the mode of the new file to agree with the old.
  1674. X     */
  1675. X    if (statres==0)
  1676. X        chmod (fname, statbuf.st_mode);
  1677. X
  1678. X    return TRUE;
  1679. X}
  1680. !EOR!
  1681. echo extracting - help.c
  1682. sed 's/^X//' > help.c << '!EOR!'
  1683. X/* $Header: /nw/tony/src/stevie/src/RCS/help.c,v 1.9 89/08/06 09:50:09 tony Exp $
  1684. X *
  1685. X * Routine to display a command summary.
  1686. X * (Dave Tutelman note:
  1687. X *    I added the ability to page backwards and forwards through help.
  1688. X *    In order to minimize the abuse to the existing code, I used
  1689. X *    "goto"s and labeled each screen.  It's not the way I would have
  1690. X *    done help from scratch, but it's not TOO ugly.
  1691. X * )
  1692. X */
  1693. X
  1694. X#include <ctype.h>
  1695. X#include "stevie.h"
  1696. X#include "ascii.h"
  1697. X#include "keymap.h"
  1698. X
  1699. X/* Macro to show help screen 'n'.
  1700. X * If C supported label types, it'd be cleaner to do it that way. */
  1701. X#define    SHOWHELP( n )    switch(n) {        \
  1702. X            case 0: goto Screen0;   \
  1703. X            case 1: goto Screen1;    \
  1704. X            case 2: goto Screen2;    \
  1705. X            case 3: goto Screen3;    \
  1706. X            case 4: goto Screen4;    \
  1707. X            case 5: goto Screen5;    \
  1708. X            case 6: goto Screen6;    \
  1709. X            case 7: goto Screen7;    \
  1710. X            case 8: goto Screen8;   \
  1711. X            default: return (TRUE);    }
  1712. X
  1713. Xextern    char    *Version;
  1714. X
  1715. Xstatic    int    helprow;
  1716. Xstatic    int    lastscreen = 0;        /* return to help in previous screen */
  1717. X
  1718. X#ifdef    HELP
  1719. X
  1720. Xstatic    void    longline();
  1721. X
  1722. Xbool_t
  1723. Xhelp()
  1724. X{
  1725. X    int k;
  1726. X
  1727. X    SHOWHELP( lastscreen );        /* where did we quit help last ? */
  1728. X
  1729. X/***********************************************************************
  1730. X * Zeroth Screen : Index to the help screens.
  1731. X ***********************************************************************/
  1732. X
  1733. XScreen0:
  1734. X    CLS;
  1735. X    windgoto(helprow = 0, 0);
  1736. X
  1737. Xlongline("\
  1738. X   Index to HELP Screens\n\
  1739. X   =====================\n\n");
  1740. Xlongline("\
  1741. X      0    Help index  (this screen)\n\
  1742. X      1    Positioning within file, adjusting the screen\n\
  1743. X      2    Character positioning\n\
  1744. X      3    Line positioning, marking & returning, undo & redo\n");
  1745. Xlongline("\
  1746. X      4    Insert & replace, words, sentences, paragraphs\n\
  1747. X      5    Operators, miscellaneous operations, yank & put\n\
  1748. X      6    \"Ex\" command line operations\n\
  1749. X      7    Set parameters\n\
  1750. X      8    System-specific features\n");
  1751. X
  1752. X    windgoto(0, 52);
  1753. X    longline(Version);
  1754. X
  1755. X    SHOWHELP( helpkey (0) );
  1756. X
  1757. X
  1758. X/***********************************************************************
  1759. X * First Screen:   Positioning within file, Adjusting the Screen
  1760. X ***********************************************************************/
  1761. X
  1762. XScreen1:
  1763. X    CLS;
  1764. X    windgoto(helprow = 0, 0);
  1765. X
  1766. Xlongline("\
  1767. X   Positioning within file\n\
  1768. X   =======================\n\
  1769. X      ^F             Forward screenfull\n\
  1770. X      ^B             Backward screenfull\n");
  1771. Xlongline("\
  1772. X      ^D             scroll down half screen\n\
  1773. X      ^U             scroll up half screen\n");
  1774. Xlongline("\
  1775. X      G              Goto line (end default)\n\
  1776. X      ]]             next function\n\
  1777. X      [[             previous function\n\
  1778. X      /re            next occurence of regular expression 're'\n");
  1779. Xlongline("\
  1780. X      ?re            prior occurence of regular expression 're'\n\
  1781. X      n              repeat last / or ?\n\
  1782. X      N              reverse last / or ?\n\
  1783. X      %              find matching (, ), {, }, [, or ]\n");
  1784. Xlongline("\
  1785. X\n\
  1786. X   Adjusting the screen\n\
  1787. X   ====================\n\
  1788. X      ^L             Redraw the screen\n\
  1789. X      ^E             scroll window down 1 line\n\
  1790. X      ^Y             scroll window up 1 line\n");
  1791. Xlongline("\
  1792. X      z<RETURN>      redraw, current line at top\n\
  1793. X      z-             ... at bottom\n\
  1794. X      z.             ... at center\n");
  1795. X
  1796. X    SHOWHELP( helpkey (1) );
  1797. X
  1798. X
  1799. X/***********************************************************************
  1800. X * Second Screen:   Character positioning
  1801. X ***********************************************************************/
  1802. X
  1803. XScreen2:
  1804. X    CLS;
  1805. X    windgoto(helprow = 0, 0);
  1806. X
  1807. Xlongline("\
  1808. X   Character Positioning\n\
  1809. X   =====================\n\
  1810. X      ^              first non-white\n\
  1811. X      0              beginning of line\n\
  1812. X      $              end of line\n\
  1813. X      h              backward\n");
  1814. Xlongline("\
  1815. X      l              forward\n\
  1816. X      ^H             same as h\n\
  1817. X      space          same as l\n\
  1818. X      fx             find 'x' forward\n");
  1819. Xlongline("\
  1820. X      Fx             find 'x' backward\n\
  1821. X      tx             upto 'x' forward\n\
  1822. X      Tx             upto 'x' backward\n\
  1823. X      ;              Repeat last f, F, t, or T\n");
  1824. Xlongline("\
  1825. X      ,              inverse of ;\n\
  1826. X      |              to specified column\n\
  1827. X      %              find matching (, ), {, }, [, or ]\n");
  1828. X
  1829. X    SHOWHELP( helpkey (2) );
  1830. X
  1831. X
  1832. X/***********************************************************************
  1833. X * Third Screen:   Line Positioning, Marking and Returning
  1834. X ***********************************************************************/
  1835. X
  1836. XScreen3:
  1837. X    CLS;
  1838. X    windgoto(helprow = 0, 0);
  1839. X
  1840. Xlongline("\
  1841. X    Line Positioning\n\
  1842. X    ================\n\
  1843. X    H           home window line\n\
  1844. X    L           last window line\n\
  1845. X    M           middle window line\n");
  1846. Xlongline("\
  1847. X    +           next line, at first non-white\n\
  1848. X    -           previous line, at first non-white\n\
  1849. X    CR          return, same as +\n\
  1850. X    j           next line, same column\n\
  1851. X    k           previous line, same column\n");
  1852. X
  1853. Xlongline("\
  1854. X\n\
  1855. X    Marking and Returning\n\
  1856. X    =====================\n\
  1857. X    ``          previous context\n\
  1858. X    ''          ... at first non-white in line\n");
  1859. Xlongline("\
  1860. X    mx          mark position with letter 'x'\n\
  1861. X    `x          to mark 'x'\n\
  1862. X    'x          ... at first non-white in line\n");
  1863. X
  1864. Xlongline("\n\
  1865. X    Undo  &  Redo\n\
  1866. X    =============\n\
  1867. X    u           undo last change\n\
  1868. X    U           restore current line\n\
  1869. X    .           repeat last change\n");
  1870. X
  1871. X    SHOWHELP( helpkey (3) );
  1872. X
  1873. X
  1874. X/***********************************************************************
  1875. X * Fourth Screen:   Insert & Replace,
  1876. X ***********************************************************************/
  1877. X
  1878. XScreen4:
  1879. X    CLS;
  1880. X    windgoto(helprow = 0, 0);
  1881. X
  1882. Xlongline("\
  1883. X    Insert and Replace\n\
  1884. X    ==================\n\
  1885. X    a           append after cursor\n\
  1886. X    i           insert before cursor\n\
  1887. X    A           append at end of line\n\
  1888. X    I           insert before first non-blank\n");
  1889. Xlongline("\
  1890. X    o           open line below\n\
  1891. X    O           open line above\n\
  1892. X    rx          replace single char with 'x'\n\
  1893. X    R           replace characters\n");
  1894. Xif (! P(P_TO))
  1895. Xlongline("\
  1896. X    ~           change case (upper/lower) of single char\n");
  1897. X
  1898. Xlongline("\
  1899. X\n\
  1900. X    Words, sentences, paragraphs\n\
  1901. X    ============================\n\
  1902. X    w           word forward\n\
  1903. X    b           back word\n\
  1904. X    e           end of word\n\
  1905. X    )           to next sentence\n\
  1906. X    }           to next paragraph\n");
  1907. Xlongline("\
  1908. X    (           back sentence\n\
  1909. X    {           back paragraph\n\
  1910. X    W           blank delimited word\n\
  1911. X    B           back W\n\
  1912. X    E           to end of W\n");
  1913. X
  1914. X    SHOWHELP( helpkey (4) );
  1915. X
  1916. X
  1917. X/***********************************************************************
  1918. X * Fifth Screen:   Operators, Misc. operations, Yank & Put
  1919. X ***********************************************************************/
  1920. X
  1921. XScreen5:
  1922. X    CLS;
  1923. X    windgoto(helprow = 0, 0);
  1924. X
  1925. Xlongline("\
  1926. X    Operators (double to affect lines)\n\
  1927. X    ==================================\n\
  1928. X    d           delete\n\
  1929. X    c           change\n");
  1930. Xlongline("\
  1931. X    <           left shift\n\
  1932. X    >           right shift\n\
  1933. X    y           yank to buffer\n\
  1934. X    !           filter lines (command name follows)\n");
  1935. Xif (P(P_TO))
  1936. Xlongline("\
  1937. X    ~           reverse case (upper/lower)\n");
  1938. X
  1939. Xlongline("\n\
  1940. X    Miscellaneous operations\n\
  1941. X    ========================\n\
  1942. X    C           change rest of line\n\
  1943. X    D           delete rest of line\n\
  1944. X    s           substitute chars\n");
  1945. Xlongline("\
  1946. X    S           substitute lines (not yet)\n\
  1947. X    J           join lines\n\
  1948. X    x           delete characters\n\
  1949. X    X           ... before cursor\n");
  1950. X
  1951. Xlongline("\n\
  1952. X    Yank and Put\n\
  1953. X    ============\n\
  1954. X    p           put back text\n\
  1955. X    P           put before\n\
  1956. X    Y           yank lines");
  1957. X
  1958. X    SHOWHELP( helpkey (5) );
  1959. X
  1960. X
  1961. X/***********************************************************************
  1962. X * Sixth Screen:   Command-line operations
  1963. X ***********************************************************************/
  1964. X
  1965. XScreen6:
  1966. X    CLS;
  1967. X    windgoto(helprow = 0, 0);
  1968. X
  1969. Xlongline("\
  1970. X    EX command-line operations\n\
  1971. X    ==========================\n");
  1972. Xlongline("\
  1973. X    :w          write back changes\n\
  1974. X    :wq         write and quit\n\
  1975. X    :x          write if modified, and quit\n\
  1976. X    :q          quit\n\
  1977. X    :q!         quit, discard changes\n\
  1978. X    :e name     edit file 'name'\n\
  1979. X    :e!         reedit, discard changes\n");
  1980. Xif (P(P_TG))
  1981. Xlongline("\
  1982. X    :e #        edit alternate file\n");
  1983. Xelse
  1984. Xlongline("\
  1985. X    :e #        edit alternate file (also ctrl-^)\n");
  1986. Xlongline("\
  1987. X    :w name     write file 'name'\n\
  1988. X    :n          edit next file in arglist\n\
  1989. X    :N          edit prior file in arglist\n\
  1990. X    :rew        rewind arglist\n\
  1991. X    :f          show current file and lines\n");
  1992. Xlongline("\
  1993. X    :f file     change current file name\n\
  1994. X    :g/pat/p|d  global command (print or delete only)\n\
  1995. X    :s/p1/p2/   text substitution (trailing 'g' optional)\n\
  1996. X    :ta tag     to tag file entry 'tag'\n\
  1997. X    ^]          :ta, current word is tag\n");
  1998. Xif (P(P_TG))
  1999. Xlongline("\
  2000. X    :untag      back to before last ':ta' (also ctrl-^)\n");
  2001. Xlongline("\
  2002. X    :sh         run an interactive shell\n\
  2003. X    :!cmd       execute a shell command\n\
  2004. X");
  2005. X
  2006. X    SHOWHELP( helpkey (6) );
  2007. X
  2008. X
  2009. X/***********************************************************************
  2010. X * Seventh Screen:   Set parameters
  2011. X ***********************************************************************/
  2012. X
  2013. XScreen7:
  2014. X    CLS;
  2015. X    windgoto(helprow = 0, 0);
  2016. X
  2017. Xlongline("\
  2018. X    Set Parameters\n\
  2019. X    ==============\n");
  2020. Xlongline("\
  2021. X    :set param-name[=param-value]   to set\n\
  2022. X    :set sm, :set nosm, :set co=23  examples\n\
  2023. X    :set all    display all values\n\
  2024. X    :set        display non-default values\n\n");
  2025. Xlongline("Abbrev, name, and current value:\n");
  2026. Xhparm(P_AI); hparm(P_SM); longline("\n");
  2027. Xhparm(P_BK); hparm(P_CO); longline("\n");
  2028. Xhparm(P_TS); hparm(P_MO); longline("\n");
  2029. Xhparm(P_IC); hparm(P_ML); longline("\n");
  2030. Xhparm(P_TG); hparm(P_TO); longline("\n");
  2031. Xhparm(P_EB); hparm(P_VB); longline("\n");
  2032. Xhparm(P_LI); hparm(P_NU); longline("\n");
  2033. Xhparm(P_SS); longline(" (# of lines for ^D, ^U)\n");
  2034. Xhparm(P_LS); longline(" (show tabs, newlines graphically)\n");
  2035. Xhparm(P_RP); longline(" (min # of lines to report on oper)\n");
  2036. Xhparm(P_WS); longline(" (search wraps around end of file)\n");
  2037. Xhparm(P_CR); longline(" (write newline to file as CR-LF)\n");
  2038. X
  2039. X    SHOWHELP( helpkey (7) );
  2040. X
  2041. X
  2042. X/***********************************************************************
  2043. X * Eighth Screen:   System-Specific Features for DOS and OS/2
  2044. X ***********************************************************************/
  2045. X
  2046. XScreen8:
  2047. X    CLS;
  2048. X    windgoto(helprow = 0, 0);
  2049. X
  2050. Xlongline("\
  2051. X    MSDOS & OS/2 Special Keys\n\
  2052. X    =========================\n");
  2053. Xlongline("\
  2054. X    The cursor keypad does pretty much what you'd expect,\n");
  2055. Xlongline("\
  2056. X    as long as you're not in text entry mode:\n\
  2057. X\n\
  2058. X    Home, End, PgUp, PgDn, and the arrow keys navigate.\n\
  2059. X    Insert    enter text before cursor.\n\
  2060. X    Delete    delete character at the cursor.\n\n");
  2061. X
  2062. Xlongline("\
  2063. X    Function Keys\n\
  2064. X    =============\n\
  2065. X    F1      Help\n\
  2066. X    F2      Next file (:n)             Shift-F2  discard changes (:n!)\n\
  2067. X    F3      Previous file (:N)         Shift-F3  discard changes (:N!)\n");
  2068. Xlongline("\
  2069. X    F4      Alternate file (:e #)      Shift-F4  discard changes (:e! #)\n\
  2070. X    F5      Rewind file list (:rew)    Shift-F5  discard changes (:rew!)\n\
  2071. X    F6      Next function (]])         Shift-F6  Prev. function ([[)\n\
  2072. X    F8      Global subst. (:1,$s/)\n\
  2073. X    F10     Save & quit (:x)           Shift-F10 discard changes (:q!)");
  2074. X
  2075. X    SHOWHELP( helpkey (8) );
  2076. X
  2077. X}
  2078. X
  2079. X
  2080. X/*    longline (p)
  2081. X *    Put the string p into the buffer, expanding newlines.
  2082. X */
  2083. Xstatic void
  2084. Xlongline(p)
  2085. Xchar    *p;
  2086. X{
  2087. X    register char    *s;
  2088. X
  2089. X    for ( s = p; *s ;s++ ) {
  2090. X        if ( *s == '\n' )
  2091. X            windgoto(++helprow, 0);
  2092. X        else
  2093. X            outchar(*s);
  2094. X    }
  2095. X}
  2096. X
  2097. X/*    hparm (n)
  2098. X *    Put the help info for param #n into the buffer.
  2099. X */
  2100. Xhparm (p)
  2101. X  int p;
  2102. X{
  2103. X    char    buf[25];
  2104. X    char    *bp;
  2105. X
  2106. X    sprintf(buf, "     %6s  %-10s  ",
  2107. X            params[p].shortname, params[p].fullname);
  2108. X    bp = buf + strlen (buf);
  2109. X    if (params[p].flags & P_NUM)    /* numeric param */
  2110. X        sprintf(bp, "%-3d", params[p].value);
  2111. X    else {                /* Boolean param */
  2112. X        if (params[p].value)
  2113. X            strcpy (bp, "yes");
  2114. X        else
  2115. X            strcpy (bp, "no ");
  2116. X    }
  2117. X    longline (buf);
  2118. X}
  2119. X
  2120. X/* Get keystroke and return instructions on what to do next.
  2121. X * Argument is current help screen.
  2122. X * Return value is target help screen, or -1 to quit help.
  2123. X */
  2124. X
  2125. X#ifdef DOS
  2126. X#  define    NSCREEN    8
  2127. X#else
  2128. X#ifdef OS2
  2129. X#  define    NSCREEN 8
  2130. X#else
  2131. X#  define    NSCREEN 7
  2132. X#endif
  2133. X#endif
  2134. X
  2135. Xint
  2136. Xhelpkey (n)
  2137. X  int n;
  2138. X{
  2139. X    static int    c = '\0';
  2140. X    int    prevkey;
  2141. X    char    banner [16];
  2142. X
  2143. X    /* Start with instructions on navigating Help */
  2144. X    strcpy (banner, "PAGE 0 OF HELP");
  2145. X    banner [5] = (char)n + '0';
  2146. X    windgoto(helprow = Rows-4, 63);
  2147. X    longline(banner);
  2148. X    windgoto(helprow = Rows-3, 63);
  2149. X    longline("^^^^^^^^^^^^^^");
  2150. X    windgoto(helprow = Rows-2, 54);
  2151. X    longline("<Press Esc to quit Help>");
  2152. X    windgoto(helprow = Rows-1, 44);
  2153. X    longline("<Other keys navigate Help screens>\n");
  2154. X
  2155. X    /* Now get keystrokes till we get a valid one */
  2156. X    while (1) {
  2157. X        prevkey = c;
  2158. X        c = vgetc();
  2159. X        switch (c) {
  2160. X          /* cases for Next Screen */
  2161. X          case ' ':      case '\t':
  2162. X          case '\n':      case '\r':    case '+':
  2163. X          case K_DARROW:
  2164. X          case 'f':      case CTRL('F'):
  2165. X          case CTRL('D'): case CTRL('Y'):
  2166. X          case 'n':      case 'N':    case CTRL('N'):
  2167. X          case 'j':
  2168. X            if (n < NSCREEN)    return (n+1);
  2169. X            break;
  2170. X
  2171. X          /* cases for Previous Screen */
  2172. X          case BS:      case '-':
  2173. X          case K_UARROW:
  2174. X          case 'b':      case CTRL('B'):
  2175. X          case CTRL('U'): case CTRL('E'):
  2176. X          case 'p':      case 'P':    case CTRL('P'):
  2177. X          case 'k':
  2178. X            if (n > 0) return (n-1);
  2179. X            break;
  2180. X
  2181. X          /* cases for Quit Help */
  2182. X          case ESC:
  2183. X          case 'Q':
  2184. X          case 'q':
  2185. X          case 'X':
  2186. X          case 'x':
  2187. X            lastscreen = n;        /* remember where we quit */
  2188. X            return (-1);
  2189. X
  2190. X          /* "G" is presumed to be a "vi-style" go-to-line,
  2191. X           * except that we interpret it as go-to-screen.
  2192. X           */
  2193. X          case 'G':
  2194. X            /* If previous key was a number,
  2195. X             * we're already there.  Otherwise, go to
  2196. X             * last screen.
  2197. X             */
  2198. X            if (prevkey<(int)'0' || prevkey>NSCREEN+(int)'0')
  2199. X                return (NSCREEN);
  2200. X            break;
  2201. X
  2202. X          /* Default is screen number or invalid code */
  2203. X          default:
  2204. X            if (c>=(int)'0' && c<=NSCREEN+(int)'0')
  2205. X                return ( c - (int)'0' );
  2206. X            break;
  2207. X        }
  2208. X    }
  2209. X}
  2210. X
  2211. X
  2212. X#else
  2213. X
  2214. Xbool_t
  2215. Xhelp()
  2216. X{
  2217. X    msg("Sorry, help not configured");
  2218. X    return FALSE;
  2219. X}
  2220. X#endif
  2221. !EOR!
  2222. echo extracting - hexchars.c
  2223. sed 's/^X//' > hexchars.c << '!EOR!'
  2224. X/* $Header: /nw/tony/src/stevie/src/RCS/hexchars.c,v 1.4 89/03/11 22:42:27 tony Exp $
  2225. X *
  2226. X * Contains information concerning the representation of characters for
  2227. X * visual output by the editor.
  2228. X */
  2229. X
  2230. X#include "stevie.h"
  2231. X
  2232. X/*
  2233. X * This file shows how to display characters on the screen. This is
  2234. X * approach is something of an overkill. It's a remnant from the
  2235. X * original code that isn't worth messing with for now. TABS are
  2236. X * special-cased depending on the value of the "list" parameter.
  2237. X */
  2238. X
  2239. Xstruct charinfo chars[] = {
  2240. X    /* 000 */    1, NULL,
  2241. X    /* 001 */    2, "^A",
  2242. X    /* 002 */    2, "^B",
  2243. X    /* 003 */    2, "^C",
  2244. X    /* 004 */    2, "^D",
  2245. X    /* 005 */    2, "^E",
  2246. X    /* 006 */    2, "^F",
  2247. X    /* 007 */    2, "^G",
  2248. X    /* 010 */    2, "^H",
  2249. X    /* 011 */    2, "^I",
  2250. X    /* 012 */    7, "[ERROR]",    /* shouldn't occur */
  2251. X    /* 013 */    2, "^K",
  2252. X    /* 014 */    2, "^L",
  2253. X    /* 015 */    2, "^M",
  2254. X    /* 016 */    2, "^N",
  2255. X    /* 017 */    2, "^O",
  2256. X    /* 020 */    2, "^P",
  2257. X    /* 021 */    2, "^Q",
  2258. X    /* 022 */    2, "^R",
  2259. X    /* 023 */    2, "^S",
  2260. X    /* 024 */    2, "^T",
  2261. X    /* 025 */    2, "^U",
  2262. X    /* 026 */    2, "^V",
  2263. X    /* 027 */    2, "^W",
  2264. X    /* 030 */    2, "^X",
  2265. X    /* 031 */    2, "^Y",
  2266. X    /* 032 */    2, "^Z",
  2267. X    /* 033 */    2, "^[",
  2268. X    /* 034 */    2, "^\\",
  2269. X    /* 035 */    2, "^]",
  2270. X    /* 036 */    2, "^^",
  2271. X    /* 037 */    2, "^_",
  2272. X    /* 040 */    1, NULL,
  2273. X    /* 041 */    1, NULL,
  2274. X    /* 042 */    1, NULL,
  2275. X    /* 043 */    1, NULL,
  2276. X    /* 044 */    1, NULL,
  2277. X    /* 045 */    1, NULL,
  2278. X    /* 046 */    1, NULL,
  2279. X    /* 047 */    1, NULL,
  2280. X    /* 050 */    1, NULL,
  2281. X    /* 051 */    1, NULL,
  2282. X    /* 052 */    1, NULL,
  2283. X    /* 053 */    1, NULL,
  2284. X    /* 054 */    1, NULL,
  2285. X    /* 055 */    1, NULL,
  2286. X    /* 056 */    1, NULL,
  2287. X    /* 057 */    1, NULL,
  2288. X    /* 060 */    1, NULL,
  2289. X    /* 061 */    1, NULL,
  2290. X    /* 062 */    1, NULL,
  2291. X    /* 063 */    1, NULL,
  2292. X    /* 064 */    1, NULL,
  2293. X    /* 065 */    1, NULL,
  2294. X    /* 066 */    1, NULL,
  2295. X    /* 067 */    1, NULL,
  2296. X    /* 070 */    1, NULL,
  2297. X    /* 071 */    1, NULL,
  2298. X    /* 072 */    1, NULL,
  2299. X    /* 073 */    1, NULL,
  2300. X    /* 074 */    1, NULL,
  2301. X    /* 075 */    1, NULL,
  2302. X    /* 076 */    1, NULL,
  2303. X    /* 077 */    1, NULL,
  2304. X    /* 100 */    1, NULL,
  2305. X    /* 101 */    1, NULL,
  2306. X    /* 102 */    1, NULL,
  2307. X    /* 103 */    1, NULL,
  2308. X    /* 104 */    1, NULL,
  2309. X    /* 105 */    1, NULL,
  2310. X    /* 106 */    1, NULL,
  2311. X    /* 107 */    1, NULL,
  2312. X    /* 110 */    1, NULL,
  2313. X    /* 111 */    1, NULL,
  2314. X    /* 112 */    1, NULL,
  2315. X    /* 113 */    1, NULL,
  2316. X    /* 114 */    1, NULL,
  2317. X    /* 115 */    1, NULL,
  2318. X    /* 116 */    1, NULL,
  2319. X    /* 117 */    1, NULL,
  2320. X    /* 120 */    1, NULL,
  2321. X    /* 121 */    1, NULL,
  2322. X    /* 122 */    1, NULL,
  2323. X    /* 123 */    1, NULL,
  2324. X    /* 124 */    1, NULL,
  2325. X    /* 125 */    1, NULL,
  2326. X    /* 126 */    1, NULL,
  2327. X    /* 127 */    1, NULL,
  2328. X    /* 130 */    1, NULL,
  2329. X    /* 131 */    1, NULL,
  2330. X    /* 132 */    1, NULL,
  2331. X    /* 133 */    1, NULL,
  2332. X    /* 134 */    1, NULL,
  2333. X    /* 135 */    1, NULL,
  2334. X    /* 136 */    1, NULL,
  2335. X    /* 137 */    1, NULL,
  2336. X    /* 140 */    1, NULL,
  2337. X    /* 141 */    1, NULL,
  2338. X    /* 142 */    1, NULL,
  2339. X    /* 143 */    1, NULL,
  2340. X    /* 144 */    1, NULL,
  2341. X    /* 145 */    1, NULL,
  2342. X    /* 146 */    1, NULL,
  2343. X    /* 147 */    1, NULL,
  2344. X    /* 150 */    1, NULL,
  2345. X    /* 151 */    1, NULL,
  2346. X    /* 152 */    1, NULL,
  2347. X    /* 153 */    1, NULL,
  2348. X    /* 154 */    1, NULL,
  2349. X    /* 155 */    1, NULL,
  2350. X    /* 156 */    1, NULL,
  2351. X    /* 157 */    1, NULL,
  2352. X    /* 160 */    1, NULL,
  2353. X    /* 161 */    1, NULL,
  2354. X    /* 162 */    1, NULL,
  2355. X    /* 163 */    1, NULL,
  2356. X    /* 164 */    1, NULL,
  2357. X    /* 165 */    1, NULL,
  2358. X    /* 166 */    1, NULL,
  2359. X    /* 167 */    1, NULL,
  2360. X    /* 170 */    1, NULL,
  2361. X    /* 171 */    1, NULL,
  2362. X    /* 172 */    1, NULL,
  2363. X    /* 173 */    1, NULL,
  2364. X    /* 174 */    1, NULL,
  2365. X    /* 175 */    1, NULL,
  2366. X    /* 176 */    1, NULL,
  2367. X    /* 177 */    2, "^?",
  2368. X};
  2369. !EOR!
  2370. echo extracting - env.h
  2371. sed 's/^X//' > env.h << '!EOR!'
  2372. X/*
  2373. X * The defines in this file establish the environment we're compiling
  2374. X * in. Set these appropriately before compiling the editor.
  2375. X */
  2376. X
  2377. X/*
  2378. X * One (and only 1) of the following defines should be uncommented.
  2379. X * Most of the code is pretty machine-independent. Machine dependent
  2380. X * code goes in a file like tos.c or unix.c. The only other place
  2381. X * where machine dependent code goes is term.h for escape sequences.
  2382. X */
  2383. X
  2384. X/* #define    ATARI            /* For the Atari ST */
  2385. X#define    UNIX            /* System V or BSD */
  2386. X/* #define    OS2            /* Microsoft OS/2 1.1 */
  2387. X/* #define    DOS            /* MSDOS 3.3 (on AT) */
  2388. X/*
  2389. X * If DOS is defined, then a number of other defines are possible:
  2390. X */
  2391. X#ifdef    DOS
  2392. X#define    TURBOC        /* Use Borland Turbo C.  Otherwise, the code
  2393. X             * uses Microsoft C.
  2394. X             */
  2395. X/* #define    BIOS    /* Display uses the BIOS routines, rather than
  2396. X             * depending on an ANSI driver.  More
  2397. X             * self-contained, and supports colors and
  2398. X             * the following param (only legal if BIOS defined).
  2399. X             */
  2400. X#endif
  2401. X
  2402. X/*
  2403. X * If UNIX is defined above, then BSD may be defined.
  2404. X */
  2405. X#ifdef    UNIX
  2406. X/* #define    BSD            /* Berkeley UNIX */
  2407. X#endif
  2408. X
  2409. X/*
  2410. X * If ATARI is defined, MINIX may be defined. Otherwise, the editor
  2411. X * is set up to compile using the Sozobon C compiler under TOS.
  2412. X */
  2413. X#ifdef    ATARI
  2414. X#define    MINIX            /* Minix for the Atari ST */
  2415. X#endif
  2416. X
  2417. X/*
  2418. X * The yank buffer is still static, but its size can be specified
  2419. X * here to override the default of 4K.
  2420. X */
  2421. X/* #define    YBSIZE    8192        /* yank buffer size */
  2422. X
  2423. X/*
  2424. X * STRCSPN should be defined if the target system doesn't have the
  2425. X * routine strcspn() available. See regexp.c for details.
  2426. X */
  2427. X
  2428. X#ifdef    ATARI
  2429. X
  2430. X#ifdef    MINIX
  2431. X#define    STRCSPN
  2432. X#endif
  2433. X
  2434. X#endif
  2435. X
  2436. X/*
  2437. X * The following defines control the inclusion of "optional" features. As
  2438. X * the code size of the editor grows, it will probably be useful to be able
  2439. X * to tailor the editor to get the features you most want in environments
  2440. X * with code size limits.
  2441. X *
  2442. X * TILDEOP
  2443. X *    Normally the '~' command works on a single character. This define
  2444. X *    turns on code that allows it to work like an operator. This is
  2445. X *    then enabled at runtime with the "tildeop" parameter.
  2446. X *
  2447. X * HELP
  2448. X *    If defined, a series of help screens may be views with the ":help"
  2449. X *    command. This eats a fair amount of data space.
  2450. X *
  2451. X * TERMCAP
  2452. X *    If defined, STEVIE uses TERMCAP to determine the escape sequences
  2453. X *    to control the screen; if so, TERMCAP support had better be there.
  2454. X *    If not defined, you generally get hard-coded escape sequences for
  2455. X *    some "reasonable" terminal. In Minix, this means the console. For
  2456. X *    UNIX, this means an ANSI standard terminal. For MSDOS, this means
  2457. X *    a good ANSI driver (like NANSI.SYS, not ANSI.SYS).
  2458. X *    See the file "term.h" for details about specific environments.
  2459. X *
  2460. X * TAGSTACK
  2461. X *    If defined, this includes code that stacks calls to ':ta'.  The
  2462. X *    additional command ':untag' pops the stack back to the point at
  2463. X *    which the call to ':ta' was made.  In this mode, if the tag stack
  2464. X *    is not empty, Ctrl-^ will be interpreted as ':untag' rather than
  2465. X *    ':e #'.
  2466. X *
  2467. X */
  2468. X#define    TILDEOP        /* enable tilde to be an operator */
  2469. X#define    HELP        /* enable help command */
  2470. X#define    TERMCAP        /* enable termcap support */
  2471. X#define    TAGSTACK    /* enable stacking calls to tags */
  2472. !EOR!
  2473. echo extracting - keymap.h
  2474. sed 's/^X//' > keymap.h << '!EOR!'
  2475. X/*
  2476. X * $Header: /nw/tony/src/stevie/src/RCS/keymap.h,v 1.2 89/03/11 22:42:30 tony Exp $
  2477. X *
  2478. X * Keycode definitions for special keys
  2479. X *
  2480. X * On systems that have any of these keys, the routine 'inchar' in the
  2481. X * machine-dependent code should return one of the codes here.
  2482. X */
  2483. X
  2484. X#define    K_HELP        0x80
  2485. X#define    K_UNDO        0x81
  2486. X#define    K_INSERT    0x82
  2487. X#define    K_HOME        0x83
  2488. X#define    K_UARROW    0x84
  2489. X#define    K_DARROW    0x85
  2490. X#define    K_LARROW    0x86
  2491. X#define    K_RARROW    0x87
  2492. X#define    K_CCIRCM    0x88    /* control-circumflex */
  2493. X
  2494. X#define    K_F1        0x91    /* function keys */
  2495. X#define    K_F2        0x92
  2496. X#define    K_F3        0x93
  2497. X#define    K_F4        0x94
  2498. X#define    K_F5        0x95
  2499. X#define    K_F6        0x96
  2500. X#define    K_F7        0x97
  2501. X#define    K_F8        0x98
  2502. X#define    K_F9        0x99
  2503. X#define    K_F10        0x9a
  2504. X
  2505. X#define    K_SF1        0xa1    /* shifted function keys */
  2506. X#define    K_SF2        0xa2
  2507. X#define    K_SF3        0xa3
  2508. X#define    K_SF4        0xa4
  2509. X#define    K_SF5        0xa5
  2510. X#define    K_SF6        0xa6
  2511. X#define    K_SF7        0xa7
  2512. X#define    K_SF8        0xa8
  2513. X#define    K_SF9        0xa9
  2514. X#define    K_SF10        0xaa
  2515. !EOR!
  2516. echo extracting - ops.h
  2517. sed 's/^X//' > ops.h << '!EOR!'
  2518. X/* $Header: /nw/tony/src/stevie/src/RCS/ops.h,v 1.2 89/07/19 08:08:21 tony Exp $
  2519. X *
  2520. X * Macros and declarations for the operator code in ops.c
  2521. X */
  2522. X
  2523. X/*
  2524. X * Operators
  2525. X */
  2526. X#define    NOP    0        /* no pending operation */
  2527. X#define    DELETE    1
  2528. X#define    YANK    2
  2529. X#define    CHANGE    3
  2530. X#define    LSHIFT    4
  2531. X#define    RSHIFT    5
  2532. X#define    FILTER    6
  2533. X#define    TILDE    7
  2534. X
  2535. Xextern    int    operator;        /* current pending operator */
  2536. X
  2537. X/*
  2538. X * When a cursor motion command is made, it is marked as being a character
  2539. X * or line oriented motion. Then, if an operator is in effect, the operation
  2540. X * becomes character or line oriented accordingly.
  2541. X *
  2542. X * Character motions are marked as being inclusive or not. Most char.
  2543. X * motions are inclusive, but some (e.g. 'w') are not.
  2544. X */
  2545. X
  2546. X/*
  2547. X * Cursor motion types
  2548. X */
  2549. X#define    MBAD    (-1)        /* 'bad' motion type marks unusable yank buf */
  2550. X#define    MCHAR    0
  2551. X#define    MLINE    1
  2552. X
  2553. Xextern    int    mtype;            /* type of the current cursor motion */
  2554. Xextern    bool_t    mincl;            /* true if char motion is inclusive */
  2555. X
  2556. Xextern    LPTR    startop;        /* cursor pos. at start of operator */
  2557. X
  2558. X/*
  2559. X * Macro to get current character from a LPTR * value.
  2560. X */
  2561. X#define    CHAR( lpp )    lpp->linep->s[lpp->index]
  2562. X
  2563. X/*
  2564. X * Functions defined in ops.c
  2565. X */
  2566. Xvoid    doshift(), dodelete(), doput(), dochange(), dofilter();
  2567. X#ifdef    TILDEOP
  2568. Xvoid    dotilde();
  2569. X#endif
  2570. Xbool_t    dojoin(), doyank();
  2571. Xvoid    startinsert();
  2572. !EOR!
  2573. echo extracting - param.h
  2574. sed 's/^X//' > param.h << '!EOR!'
  2575. X/* $Header: /nw/tony/src/stevie/src/RCS/param.h,v 1.8 89/08/02 10:59:35 tony Exp $
  2576. X *
  2577. X * Settable parameters
  2578. X */
  2579. X
  2580. Xstruct    param {
  2581. X    char    *fullname;    /* full parameter name */
  2582. X    char    *shortname;    /* permissible abbreviation */
  2583. X    int    value;        /* parameter value */
  2584. X    int    flags;
  2585. X};
  2586. X
  2587. Xextern    struct    param    params[];
  2588. X
  2589. X/*
  2590. X * Flags
  2591. X */
  2592. X#define    P_BOOL        0x01    /* the parameter is boolean */
  2593. X#define    P_NUM        0x02    /* the parameter is numeric */
  2594. X#define    P_CHANGED    0x04    /* the parameter has been changed */
  2595. X
  2596. X/*
  2597. X * The following are the indices in the params array for each parameter
  2598. X */
  2599. X
  2600. X/*
  2601. X * Numeric parameters
  2602. X */
  2603. X#define    P_TS        0    /* tab size */
  2604. X#define    P_SS        1    /* scroll size */
  2605. X#define    P_RP        2    /* report */
  2606. X#define    P_LI        3    /* lines */
  2607. X
  2608. X/*
  2609. X * Boolean parameters
  2610. X */
  2611. X#define    P_VB        4    /* visual bell */
  2612. X#define    P_SM        5    /* showmatch */
  2613. X#define    P_WS        6    /* wrap scan */
  2614. X#define    P_EB        7    /* error bells */
  2615. X#define    P_MO        8    /* show mode */
  2616. X#define    P_BK        9    /* make backups when writing out files */
  2617. X#define    P_CR        10    /* use cr-lf to terminate lines on writes */
  2618. X#define    P_LS        11    /* show tabs and newlines graphically */
  2619. X#define    P_IC        12    /* ignore case in searches */
  2620. X#define    P_AI        13    /* auto-indent */
  2621. X#define    P_NU        14    /* number lines on the screen */
  2622. X#define    P_ML        15    /* enables mode-lines processing */
  2623. X#define    P_TO        16    /* if true, tilde is an operator */
  2624. X#define    P_TE        17    /* ignored; here for compatibility */
  2625. X#define    P_TG        18    /* enables stacking of tag calls */
  2626. X#define    P_CO        19    /* color/attribute setting */
  2627. X
  2628. X/*
  2629. X * Macro to get the value of a parameter
  2630. X */
  2631. X#define    P(n)    (params[n].value)
  2632. !EOR!
  2633. echo extracting - regexp.h
  2634. sed 's/^X//' > regexp.h << '!EOR!'
  2635. X/*
  2636. X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  2637. X *
  2638. X * This is NOT the original regular expression code as written by
  2639. X * Henry Spencer. This code has been modified specifically for use
  2640. X * with the STEVIE editor, and should not be used apart from compiling
  2641. X * STEVIE. If you want a good regular expression library, get the
  2642. X * original code. The copyright notice that follows is from the
  2643. X * original.
  2644. X *
  2645. X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  2646. X *
  2647. X * Definitions etc. for regexp(3) routines.
  2648. X *
  2649. X * Caveat:  this is V8 regexp(3) [actually, a reimplementation thereof],
  2650. X * not the System V one.
  2651. X */
  2652. X#define NSUBEXP  10
  2653. Xtypedef struct regexp {
  2654. X    char *startp[NSUBEXP];
  2655. X    char *endp[NSUBEXP];
  2656. X    char regstart;        /* Internal use only. */
  2657. X    char reganch;        /* Internal use only. */
  2658. X    char *regmust;        /* Internal use only. */
  2659. X    int regmlen;        /* Internal use only. */
  2660. X    char program[1];    /* Unwarranted chumminess with compiler. */
  2661. X} regexp;
  2662. X
  2663. Xextern regexp *regcomp();
  2664. Xextern int regexec();
  2665. Xextern void regsub();
  2666. Xextern void regerror();
  2667. X
  2668. X#ifndef    ORIGINAL
  2669. Xextern int reg_ic;        /* set non-zero to ignore case in searches */
  2670. X#endif
  2671. !EOR!
  2672. echo extracting - regmagic.h
  2673. sed 's/^X//' > regmagic.h << '!EOR!'
  2674. X/*
  2675. X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  2676. X *
  2677. X * This is NOT the original regular expression code as written by
  2678. X * Henry Spencer. This code has been modified specifically for use
  2679. X * with the STEVIE editor, and should not be used apart from compiling
  2680. X * STEVIE. If you want a good regular expression library, get the
  2681. X * original code. The copyright notice that follows is from the
  2682. X * original.
  2683. X *
  2684. X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  2685. X *
  2686. X * The first byte of the regexp internal "program" is actually this magic
  2687. X * number; the start node begins in the second byte.
  2688. X */
  2689. X#define    MAGIC    0234
  2690. !EOR!
  2691.  
  2692.