home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / stevie.zoo / stevie.2 < prev    next >
Encoding:
Text File  |  1990-03-14  |  60.6 KB  |  2,684 lines

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