home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2878 / file.c < prev   
Encoding:
C/C++ Source or Header  |  1991-02-28  |  20.5 KB  |  732 lines

  1. /*
  2. *  File commands.
  3. */
  4. #include        "def.h"
  5.  
  6. char    load_file ();
  7. char    readin ();
  8. void    makename ();
  9. bool    writeout ();
  10. bool    parse_f_name ();
  11.  
  12. extern    char    MSG_rd_file[];
  13. extern    char    MSG_trash[];
  14. extern    char    MSG_ins_file[];
  15. extern    char    MSG_not_fnd[];
  16. extern    char    MSG_visit[];
  17. extern    char    MSG_view[];
  18. extern    char    MSG_buf_ex[];
  19. extern    char    MSG_old_buf[];
  20. extern    char    MSG_buf_nam[];
  21. extern    char    MSG_cnt_cr[];
  22. extern    char    MSG_reading[];
  23. extern    char    MSG_read_lx[];
  24. extern    char    MSG_no_mem_rd[];
  25. extern    char    MSG_wr_file[];
  26. extern    char    MSG_no_fn[];
  27. extern    char    MSG_bk_err[];
  28. extern    char    MSG_writing[];
  29. extern    char    MSG_wrot_1[];
  30. extern    char    MSG_wrot_n[];
  31. extern    char    MSG_fil_nam[];
  32. extern    char    MSG_null[];
  33. extern    char    ERR_parse_fn[];
  34. extern    char    ERR_addr_neg[];
  35. extern    char    ERR_f_size[];
  36.  
  37. #include    "lintfunc.dec"
  38.  
  39. static int  ughlyflag = FALSE;
  40.  
  41. /*
  42. * Read a file into the current
  43. * buffer. This is really easy; all you do it
  44. * find the name of the file, and call the standard
  45. * "read a file into the current buffer" code.
  46. */
  47. char    fileread ()
  48. {
  49.     register char   s;
  50.     char    fname[NFILEN];
  51.     A32     start, end;
  52.  
  53.     if ((s = ereply (MSG_rd_file, fname, NFILEN, NULL)) != TRUE)
  54.         return (s);
  55.     if (parse_f_name (fname, &start, &end))
  56.     {
  57.         adjustcase (fname);
  58.         return (readin (fname, start, end));
  59.     }
  60.     return (TRUE);
  61. }
  62.  
  63.  
  64. /* insert file into current buffer - use readin, and yank
  65. */
  66. char    fileinsert ()
  67. {
  68.     register char   s;
  69.     char    bname[NBUFN],
  70.             fname[NFILEN];
  71.     A32     start, end;
  72.     register char  *trash = MSG_trash;
  73.  
  74.     strcpy (bname, curbp -> b_bname);/* save current buffer */
  75.     if ((s = _usebuffer (trash)) == 0)/* temp buffer */
  76.         return (s);
  77.     if ((s = ereply (MSG_ins_file, fname, NFILEN, NULL)) != TRUE)
  78.         return (s);
  79.     /* if file name and starting and ending addresses are good */ 
  80.     if (parse_f_name (fname, &start, &end))
  81.     {
  82.         adjustcase (fname);
  83.         if ((s = readin (fname, start, end)) == 0)
  84.             {
  85.             writ_echo (MSG_not_fnd);
  86.             _usebuffer (bname);
  87.             _killbuffer (trash);
  88.             return (s);
  89.             }
  90.         if ((s = _usebuffer (bname)) == 0)
  91.             {
  92.             _killbuffer (trash);
  93.             return (s);
  94.             }
  95.         if ((s = _yankbuffer (trash)) == 0)
  96.             {
  97.             _killbuffer (trash);
  98.             return (s);
  99.             }
  100.         writ_echo (okmsg);
  101.     }
  102.     else
  103.     {
  104.         _usebuffer (bname);
  105.         _killbuffer (trash);
  106.         return (FALSE);
  107.     }
  108.     if ((s = _killbuffer (trash)) == 0)
  109.         return (s);
  110.     wind_on_dot (curwp);
  111.     return (s);
  112. }
  113.  
  114.  
  115. /*
  116. * Select a file for editing.
  117. * Look around to see if you can find the
  118. * fine in another buffer; if you can find it
  119. * just switch to the buffer. If you cannot find
  120. * the file, create a new buffer, read in the
  121. * text, and switch to the new buffer.
  122. *
  123. * also various hacked versions for auto load, and 
  124. * file-vist with auto window split, and readonly (view-file) (jam)
  125. */
  126. char    file_visit (f, n, k)
  127. {
  128.     char    fname[NFILEN];
  129.     char    s;
  130.     A32     start, end;
  131.     if ((s = ereply (MSG_visit, fname, NFILEN, NULL)) != TRUE)
  132.         return (s);
  133.     if (!parse_f_name (fname, &start, &end))
  134.         return (FALSE);
  135.  
  136.     splitwind ();
  137.     return (load_file (fname, start, end));
  138. }
  139.  
  140.  
  141. /* like filevisit, only read only
  142. */
  143. char    viewfile ()
  144. {
  145.     char    fname[NFILEN];
  146.     char    s;
  147.     A32     start, end;
  148.  
  149.     if ((s = ereply (MSG_view, fname, NFILEN, NULL)) != TRUE)
  150.         return (s);
  151.     ughlyflag = TRUE;
  152.     if (!parse_f_name (fname, &start, &end))
  153.         return (FALSE);
  154.  
  155.     s = load_file (fname, start, end);
  156.     if (s)
  157.         curbp -> b_flag |= BFVIEW;
  158.     ughlyflag = FALSE;
  159.     return (s);
  160. }
  161.  
  162.  
  163. char    filevisit ()
  164. {
  165.     char    fname[NFILEN];
  166.     char    s;
  167.     A32     start, end;
  168.  
  169.     if ((s = ereply (MSG_visit, fname, NFILEN, NULL)) != TRUE)
  170.         return (s);
  171.     if (!parse_f_name (fname, &start, &end))
  172.         return (FALSE);
  173.  
  174.     return (load_file (fname, start, end));
  175. }
  176.  
  177.  
  178. char    load_file (fname, start, end)       /* jam */
  179. char   *fname;
  180. A32     start, end;
  181. {
  182.     register    BUFFER * bp;
  183.     register    WINDOW * wp;
  184.     register    LINE * lp;
  185.     register int    i;
  186.     char        s;
  187.     char        bname[NBUFN];
  188.     extern int  initial_load;   /* jam */
  189.     static int  append = 0;
  190.  
  191.     adjustcase (fname);
  192.     for (bp = bheadp; bp != NULL; bp = bp -> b_bufp)
  193.         {
  194.         if (strcmp (bp -> b_fname, fname) == 0)
  195.             {
  196.             if (ughlyflag == TRUE)
  197.                 {
  198.                 writ_echo (MSG_buf_ex);
  199.                 return (FALSE);
  200.                 }
  201.             if (--curbp -> b_nwnd == 0)
  202.                 {
  203.                 curbp -> buf_type = BFILE;
  204.                 curbp -> b_dotp = curwp -> w_dotp;
  205.                 curbp -> b_doto = curwp -> w_doto;
  206.                 curbp -> b_unit_offset = curwp -> w_unit_offset;
  207.                 curbp -> b_markp = curwp -> w_markp;
  208.                 curbp -> b_marko = curwp -> w_marko;
  209.                 }
  210.             curbp = bp;
  211.             curwp -> w_bufp = bp;
  212.             if (bp -> b_nwnd++ == 0)
  213.                 {
  214.                 curwp -> w_dotp = bp -> b_dotp;
  215.                 curwp -> w_doto = bp -> b_doto;
  216.                 curwp -> w_unit_offset = bp -> b_unit_offset;
  217.                 curwp -> w_markp = bp -> b_markp;
  218.                 curwp -> w_marko = bp -> b_marko;
  219.                 }
  220.             else
  221.                 {
  222.                 wp = wheadp;
  223.                 while (wp != NULL)
  224.                     {
  225.                     if (wp != curwp && wp -> w_bufp == bp)
  226.                         {
  227.                         curwp -> w_dotp = wp -> w_dotp;
  228.                         curwp -> w_doto = wp -> w_doto;
  229.                         curwp -> w_unit_offset = wp -> w_unit_offset;
  230.                         curwp -> w_markp = wp -> w_markp;
  231.                         curwp -> w_marko = wp -> w_marko;
  232.                         break;
  233.                         }
  234.                     wp = wp -> w_wndp;
  235.                     }
  236.                 }
  237.             lp = curwp -> w_dotp;
  238.             i = curwp -> w_ntrows / 2;
  239.             while (i-- && lback (lp) != curbp -> b_linep)
  240.                 lp = lback (lp);
  241.             curwp -> w_linep = lp;
  242.             curwp -> w_flag |= WFMODE | WFHARD;
  243.             if (kbdmop == NULL)
  244.                 {
  245.                 writ_echo (MSG_old_buf);
  246.                 }
  247.             return (TRUE);
  248.             }
  249.         }
  250.  
  251.     makename (bname, fname);    /* New buffer name.     */
  252.     while ((bp = bfind (bname, FALSE)) != NULL)
  253.         {
  254.         if (initial_load)       /* patch old name */
  255.             {
  256.             funky_name (bname, append++);
  257.             bp = NULL;
  258.             break;
  259.             }
  260.         s = ereply (MSG_buf_nam, bname, NBUFN, NULL);
  261.         if (s == ABORT)         /* ^G to just quit      */
  262.             return (s);
  263.         if (strcmp (bp -> b_bname, bname) == 0 || s == FALSE)
  264.             {
  265.         /* CR to clobber it     */
  266.             makename (bname, fname);
  267.             break;
  268.             }
  269.         }
  270.     if (bp == NULL && (bp = bfind (bname, TRUE)) == NULL)
  271.         {
  272.         writ_echo (MSG_cnt_cr);
  273.         return (FALSE);
  274.         }
  275.     if (--curbp -> b_nwnd == 0)
  276.         {
  277.         /* Undisplay.           */
  278.         curbp -> buf_type = BFILE;
  279.         curbp -> b_dotp = curwp -> w_dotp;
  280.         curbp -> b_doto = curwp -> w_doto;
  281.         curbp -> b_unit_offset = curwp -> w_unit_offset;
  282.         curbp -> b_markp = curwp -> w_markp;
  283.         curbp -> b_marko = curwp -> w_marko;
  284.         }
  285.     curbp = bp;                 /* Switch to it.        */
  286.     curwp -> w_bufp = bp;
  287.     curbp -> b_nwnd++;
  288.     return (readin (fname, start, end));    /* Read it in.          */
  289. }
  290.  
  291.  
  292. /*
  293. * Read the file "fname" into the current buffer.
  294. * Make all of the text in the buffer go away, after checking
  295. * for unsaved changes. This is called by the "read" command, the
  296. * "visit" command, and the mainline (for "beav file"). If the
  297. * BACKUP conditional is set, then this routine also does the read
  298. * end of backup processing. The BFBAK flag, if set in a buffer,
  299. * says that a backup should be taken. It is set when a file is
  300. * read in, but not on a new file (you don't need to make a backup
  301. * copy of nothing). Return a standard status. Print a summary
  302. * (lines read, error message) out as well.
  303. */
  304. char    readin (fname, start, end)
  305. char    fname[];
  306. A32     start, end;
  307. {
  308.     register    LINE * lp1;
  309.     register    LINE * lp2;
  310.     register    char   i;
  311.     register    WINDOW * wp;
  312.     register    BUFFER * bp;
  313.     register    char   s, m;
  314.     long        byte_cnt;
  315.     char        line[NLINE];
  316.     int         num_chars, req_chars;
  317.     char        buf[80], buf1[80];
  318.     A32         temp;
  319.  
  320.     m = TRUE;
  321.     byte_cnt = 0;
  322.     bp = curbp;                 /* Cheap.               */
  323.     if ((s = bclear (bp)) != TRUE)/* Might be old.        */
  324.         return (s);
  325. #if     BACKUP
  326.     bp -> b_flag &= ~(BFCHG | BFBAK);/* No change, backup.   */
  327. #else
  328.     bp -> b_flag &= ~BFCHG;     /* No change.           */
  329. #endif
  330.     if ((start == 0L) && (end == MAXPOS))
  331.         strcpy (bp -> b_fname, fname);
  332.     else
  333.         strcpy (bp -> b_fname, MSG_null);
  334.     if ((s = ffropen (fname)) == FIOERR || s == FIOFNF)/* jam */
  335.         goto out;
  336.     bp -> b_file_size = file_len ();  /* get the file lenth */
  337.     sprintf (buf, MSG_reading, fname);/* jam */
  338.     writ_echo (buf);
  339.     temp = ffseek (start);
  340.     if (temp != start)
  341.     {
  342.         sprintf (buf1, ERR_f_size, R_POS_FMT(curwp));
  343.         sprintf (buf, buf1, temp);
  344.         writ_echo (buf);
  345.         return (FALSE);
  346.     }
  347.     /* only read the requested number of characters */
  348.     if ((end - start) > NLINE)
  349.         req_chars = NLINE;
  350.     else
  351.         req_chars = (int)(end - start);
  352.  
  353.     while ((s = ffgetline (line, req_chars, &num_chars)) == FIOSUC)
  354.         {
  355.         if ((lp1 = lalloc(num_chars)) == NULL)
  356.             {
  357.             bp -> b_flag |= BFVIEW; /* if no memory set to read only mode */ 
  358.             m = FALSE;          /* flag memory allocation error */
  359.             break;          
  360.             }
  361.         /* this code breaks rules for knowing how lines * are stored and linked
  362.         together, oh well */
  363.         lp2 = lback (curbp -> b_linep);
  364.         lp2 -> l_fp = lp1;
  365.         lp1 -> l_fp = curbp -> b_linep;
  366.         lp1 -> l_bp = lp2;
  367.         curbp -> b_linep -> l_bp = lp1;
  368.         for (i = 0; i < num_chars; ++i)
  369.             lputc (lp1, i, line[i]);
  370.         lp1 -> l_used = num_chars;      /* number of bytes in this line */
  371.         lp1 -> l_file_offset = byte_cnt;   /* file offset from begining */
  372.         byte_cnt += (long) num_chars;   /* number of bytes read in    */
  373.         start += (long) num_chars;
  374.         if (end <= start)
  375.             break;
  376.         /* stop reading after the requested number of characters */
  377.         if (end < start + req_chars)
  378.             {
  379.             req_chars = end - start;
  380.             }
  381.         }
  382.     ffclose ();                 /* Ignore errors.       */
  383.     if (s == FIOEOF && kbdmop == NULL)
  384.         {
  385.         /* Don't zap an error.   */
  386.         sprintf (buf1, MSG_read_lx, R_POS_FMT(curwp));
  387.         sprintf (buf, buf1, byte_cnt);
  388.         writ_echo (buf);
  389.         }
  390.     if (m == FALSE && kbdmop == NULL)
  391.         {
  392.         /* Don't zap an error.   */
  393.         sprintf (buf1, MSG_no_mem_rd, R_POS_FMT(curwp));
  394.         sprintf (buf, buf1, byte_cnt);
  395.         writ_echo (buf);
  396.         }
  397.  
  398. #if     BACKUP
  399.     curbp -> b_flag |= BFBAK;   /* Need a backup.       */
  400. #endif
  401. out: 
  402.     for (wp = wheadp; wp != NULL; wp = wp -> w_wndp)
  403.         {
  404.         if (wp -> w_bufp == curbp)
  405.             {
  406.             wp -> w_linep = lforw (curbp -> b_linep);
  407.             wp -> w_dotp = lforw (curbp -> b_linep);
  408.             wp -> w_doto = 0;
  409.             wp -> w_unit_offset = 0;
  410.             wp -> w_markp = NULL;
  411.             wp -> w_marko = 0;
  412.             wp -> w_flag |= WFMODE | WFHARD;
  413.             }
  414.         }
  415.     if (s == FIOERR || s == FIOFNF)/* False if error.      */
  416.         return (FALSE);
  417.  /* so tell yank-buffer about it */
  418.     if (blistp -> b_nwnd != 0)  /* update buffer display */
  419.         listbuffers ();
  420.     return (TRUE);
  421. }
  422.  
  423.  
  424. /*
  425. * Take a file name, and from it
  426. * fabricate a buffer name. This routine knows
  427. * about the syntax of file names on the target system.
  428. * BDC1         left scan delimiter.
  429. * BDC2         optional second left scan delimiter.
  430. * BDC3         optional right scan delimiter.
  431. */
  432. void makename (bname, fname)
  433. char    bname[];
  434. char    fname[];
  435. {
  436.     register char  *cp1;
  437.     register char  *cp2;
  438.  
  439.     cp1 = &fname[0];
  440.     while (*cp1 != 0)
  441.         ++cp1;
  442. #ifdef  BDC2
  443.     while (cp1 != &fname[0] && cp1[-1] != BDC1 && cp1[-1] != BDC2)
  444.         --cp1;
  445. #else
  446.     while (cp1 != &fname[0] && cp1[-1] != BDC1)
  447.         --cp1;
  448. #endif
  449.     cp2 = &bname[0];
  450. #ifdef  BDC3
  451.     while (cp2 != &bname[NBUFN - 1] && *cp1 != 0 && *cp1 != BDC3)
  452.         *cp2++ = *cp1++;
  453. #else
  454.     while (cp2 != &bname[NBUFN - 1] && *cp1 != 0)
  455.         *cp2++ = *cp1++;
  456. #endif
  457.     *cp2 = 0;
  458. }
  459.  
  460.  
  461. /*
  462. * Ask for a file name, and write the
  463. * contents of the current buffer to that file.
  464. * Update the remembered file name and clear the
  465. * buffer changed flag. This handling of file names
  466. * is different from the earlier versions, and
  467. * is more compatable with Gosling EMACS than
  468. * with ITS EMACS.
  469. */
  470. char    filewrite ()
  471. {
  472.     register    WINDOW * wp;
  473.     register char   s;
  474.     char    fname[NFILEN];
  475.     A32     start, end;
  476.  
  477.     if ((s = ereply (MSG_wr_file, fname, NFILEN, NULL)) != TRUE)
  478.         return (s);
  479.     if (!parse_f_name (fname, &start, &end))
  480.         return (FALSE);
  481.  
  482.     adjustcase (fname);
  483.     if ((s = writeout (fname, start, end)) == TRUE)
  484.         {
  485.         strcpy (curbp -> b_fname, fname);
  486.         curbp -> b_flag &= ~BFCHG;
  487.         wp = wheadp;            /* Update mode lines.   */
  488.         while (wp != NULL)
  489.             {
  490.             if (wp -> w_bufp == curbp)
  491.                 wp -> w_flag |= WFMODE;
  492.             wp = wp -> w_wndp;
  493.             }
  494.         }
  495.  
  496. #if     BACKUP
  497.     curbp -> b_flag &= ~BFBAK;  /* No backup.           */
  498. #endif
  499.     return (s);
  500. }
  501.  
  502.  
  503. /*
  504. * Save the contents of the current buffer back into
  505. * its associated file. Do nothing if there have been no changes
  506. * (is this a bug, or a feature). Error if there is no remembered
  507. * file name. If this is the first write since the read or visit,
  508. * thet a backup copy of the file is made.
  509. */
  510. char    filesave ()
  511. {
  512.     register    WINDOW * wp;
  513.     register char   s;
  514.  
  515.     if ((curbp -> b_flag & BFCHG) == 0)/* Return, no changes.  */
  516.         return (TRUE);
  517.     if (curbp -> b_fname[0] == 0)/* Must have a name.    */
  518.         {
  519.         if (!(curbp -> b_flag & BFSAV))/* yanked buffer */
  520.             {
  521.             writ_echo (MSG_no_fn);
  522.             }
  523.         return (FALSE);
  524.         }
  525. #if     BACKUP
  526.     if ((curbp -> b_flag & BFBAK) != 0)
  527.         {
  528.         s = fbackupfile (curbp -> b_fname);
  529.         if (s == ABORT)         /* Hard error.          */
  530.             return (s);
  531.         if (s == FALSE          /* Softer error.        */
  532.                 && (s = eyesno (MSG_bk_err)) != TRUE)
  533.             return (s);
  534.         }
  535.  
  536. #endif
  537.     if ((s = writeout (curbp -> b_fname, 0L, MAXPOS)) == TRUE)
  538.         {
  539.         curbp -> b_flag &= ~BFCHG;/* No change.           */
  540.         curbp -> b_flag &= ~BFBAD;/* if it was trashed, forget it now */
  541.         wp = wheadp;            /* Update mode lines.   */
  542.         while (wp != NULL)
  543.             {
  544.             if (wp -> w_bufp == curbp)
  545.                 wp -> w_flag |= WFMODE;
  546.             wp = wp -> w_wndp;
  547.             }
  548.         }
  549.  
  550. #if     BACKUP
  551.     curbp -> b_flag &= ~BFBAK;  /* No backup.           */
  552. #endif
  553.     return (s);
  554. }
  555.  
  556. /*
  557. * This function performs the details of file
  558. * writing. Uses the file management routines in the
  559. * "fileio.c" package. The number of lines written is
  560. * displayed. Sadly, it looks inside a LINE; provide
  561. * a macro for this. Most of the grief is error
  562. * checking of some sort.
  563. */
  564. bool writeout (fn, start, end)
  565. char   *fn;
  566. A32     start, end;
  567. {
  568.     register    int    s, num_chars;
  569.     register    LINE * lp;
  570.     register    long   nbytes;
  571.     char        buf[80], buf1[80];
  572.     A32         temp;
  573.  
  574.     if ((s = ffwopen (fn)) != FIOSUC)/* Open writes message. */
  575.         return (FALSE);
  576.     temp = ffseek (start);
  577.     if (temp != start)
  578.     {
  579.         sprintf (buf1, ERR_f_size, R_POS_FMT(curwp));
  580.         sprintf (buf, buf1, temp);
  581.         writ_echo (buf);
  582.         return (FALSE);
  583.     }
  584.     sprintf (buf, MSG_writing, fn);/* jam */
  585.     writ_echo (buf);
  586.     lp = lforw (curbp -> b_linep);/* First line. */
  587.     nbytes = 0;                  /* Number of bytes.  */
  588.     temp = end - start;         /* number of bytes to write */
  589.     while (lp != curbp -> b_linep)
  590.         {
  591.         if (nbytes + (long)llength (lp) > temp)
  592.             num_chars = (int)(temp - nbytes);
  593.         else
  594.             num_chars = llength (lp);   
  595.  
  596.         if ((s = ffputline (&lp -> l_text[0], num_chars)) != FIOSUC)
  597.             break;
  598.         nbytes += num_chars;
  599.         if (temp <= nbytes)
  600.             break;
  601.         lp = lforw (lp);
  602.         }
  603.     if (s == FIOSUC)
  604.         {
  605.     /* No write error. */
  606.         s = ffclose ();
  607.         if (s == FIOSUC && kbdmop == NULL)
  608.             {
  609.             if (nbytes == 1)
  610.                 {
  611.                 writ_echo (MSG_wrot_1);
  612.                 }
  613.             else
  614.                 {
  615.                 sprintf (buf1, MSG_wrot_n, R_POS_FMT(curwp));
  616.                 sprintf (buf, buf1, (long) nbytes);
  617.                 writ_echo (buf);
  618.                 }
  619.             }
  620.         }
  621.     else                        /* Ignore close error   */
  622.         ffclose ();             /* if a write error.    */
  623.     if (s != FIOSUC)            /* Some sort of error.  */
  624.         return (FALSE);
  625.     curbp -> b_file_size = nbytes;  /* update file size */
  626.     if (blistp -> b_nwnd != 0)  /* update buffer display */
  627.         listbuffers ();
  628.     return (TRUE);
  629. }
  630.  
  631. /*
  632. * The command allows the user
  633. * to modify the file name associated with
  634. * the current buffer. It is like the "f" command
  635. * in UNIX "ed". The operation is simple; just zap
  636. * the name in the BUFFER structure, and mark the windows
  637. * as needing an update. You can type a blank line at the
  638. * prompt if you wish.
  639. */
  640. char    filename ()
  641. {
  642.     register    WINDOW * wp;
  643.     register char   s;
  644.     char    fname[NFILEN];
  645.     A32     start, end;
  646.  
  647.     if ((s = ereply (MSG_fil_nam, fname, NFILEN, NULL)) == ABORT)
  648.         return (s);
  649.     if (!parse_f_name (fname, &start, &end))
  650.         return (FALSE);
  651.  
  652.     adjustcase (fname);
  653.     curbp -> b_flag |= BFCHG;   /* jam - on name change, set modify */
  654.     BUF_START(curwp) = start;
  655.     l_fix_up (NULL);    /* adjust file offsets from first line */
  656.     strcpy (curbp -> b_fname, fname);/* Fix name.            */
  657.     wp = wheadp;                /* Update mode lines.   */
  658.     while (wp != NULL)
  659.         {
  660.         if (wp -> w_bufp == curbp)
  661.             wp -> w_flag |= WFMODE;
  662.         wp = wp -> w_wndp;
  663.         }
  664. #if     BACKUP
  665.     curbp -> b_flag &= ~BFBAK;  /* No backup.           */
  666. #endif
  667.     return (TRUE);
  668. }
  669.  
  670. /*
  671. *   Get the length parameters that were entered with the file name.
  672. *   There can be the file name only.
  673. *   There can be a file name and a starting position.
  674. *   There can be a name a starting position and an ending position.
  675. *   There can be a name a starting position and a length.
  676. *
  677. *   input:
  678. *       fn      pointer to file name string to parse.
  679. *
  680. *   output:
  681. *       fn      pointer to null terminated file name.
  682. *       start   pointer to the starting point in file (default = 0)
  683. *       end     pointer to the end point in file (default = -1)
  684. *       return  FALSE if file name or addresses are bad.
  685. */
  686. bool    parse_f_name (fn, start, end)
  687. char    *fn;
  688. A32     *start, *end;
  689.     {
  690.     char    buf[NFILEN], buf1[80], fmt[10];
  691.     int     i_cnt;
  692.     A32     temp;
  693.  
  694.     /* build up format string according to the current screen format */ 
  695.     sprintf (fmt, "%s %s %s", "%s", R_POS_FMT(curwp), R_POS_FMT(curwp));
  696.  
  697.     *start = 0L;
  698.     *end = MAXPOS;
  699.     sscanf (fn, fmt, buf, start, end);
  700.  
  701.     if (*end != MAXPOS)
  702.         {
  703.         for (i_cnt = strlen (fn) - 1; i_cnt >= 0; i_cnt--)
  704.             {
  705.             if (fn[i_cnt] == '+')
  706.                 {
  707.                 *end += *start;
  708.                 break;
  709.                 }
  710.             }
  711.         }
  712.     /* start should preceed end */
  713.     if (*start > *end)
  714.         {
  715.         sprintf (buf1, ERR_parse_fn, R_POS_FMT(curwp), R_POS_FMT(curwp));
  716.         sprintf (buf, buf1, *start, *end);
  717.         writ_echo (buf);
  718.         return (FALSE);
  719.         }
  720.  
  721.     /* error if addresses are negative */
  722.     if ((*start < 0) || (*end < 0))
  723.     {   
  724.         writ_echo (ERR_addr_neg);
  725.         return (FALSE);
  726.     }
  727.  
  728.     /* deposit null terminated file name */
  729.     strcpy (fn, buf);
  730.     return (TRUE);
  731.     }
  732.