home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / gnu / rcs-5.6.0.1-src.lha / rcs-5.6.0.1 / src / rcsedit.c < prev    next >
C/C++ Source or Header  |  1991-11-22  |  40KB  |  1,657 lines

  1. /*
  2.  *                     RCS stream editor
  3.  */
  4. /**********************************************************************************
  5.  *                       edits the input file according to a
  6.  *                       script from stdin, generated by diff -n
  7.  *                       performs keyword expansion
  8.  **********************************************************************************
  9.  */
  10.  
  11. /* Copyright (C) 1982, 1988, 1989 Walter Tichy
  12.    Copyright 1990, 1991 by Paul Eggert
  13.    Distributed under license by the Free Software Foundation, Inc.
  14.  
  15. This file is part of RCS.
  16.  
  17. RCS is free software; you can redistribute it and/or modify
  18. it under the terms of the GNU General Public License as published by
  19. the Free Software Foundation; either version 2, or (at your option)
  20. any later version.
  21.  
  22. RCS is distributed in the hope that it will be useful,
  23. but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25. GNU General Public License for more details.
  26.  
  27. You should have received a copy of the GNU General Public License
  28. along with RCS; see the file COPYING.  If not, write to
  29. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  30.  
  31. Report problems and direct all questions to:
  32.  
  33.     rcs-bugs@cs.purdue.edu
  34.  
  35. */
  36.  
  37.  
  38. /* $Log: rcsedit.c,v $
  39.  * Revision 5.11  1991/11/03  01:11:44  eggert
  40.  * Move the warning about link breaking to where they're actually being broken.
  41.  *
  42.  * Revision 5.10  1991/10/07  17:32:46  eggert
  43.  * Support piece tables even if !has_mmap.  Fix rare NFS bugs.
  44.  *
  45.  * Revision 5.9  1991/09/17  19:07:40  eggert
  46.  * SGI readlink() yields ENXIO, not EINVAL, for nonlinks.
  47.  *
  48.  * Revision 5.8  1991/08/19  03:13:55  eggert
  49.  * Add piece tables, NFS bug workarounds.  Catch odd filenames.  Tune.
  50.  *
  51.  * Revision 5.7  1991/04/21  11:58:21  eggert
  52.  * Fix errno bugs.  Add -x, RCSINIT, MS-DOS support.
  53.  *
  54.  * Revision 5.6  1991/02/25  07:12:40  eggert
  55.  * Fix setuid bug.  Support new link behavior.  Work around broken "w+" fopen.
  56.  *
  57.  * Revision 5.5  1990/12/30  05:07:35  eggert
  58.  * Fix report of busy RCS files when !defined(O_CREAT) | !defined(O_EXCL).
  59.  *
  60.  * Revision 5.4  1990/11/01  05:03:40  eggert
  61.  * Permit arbitrary data in comment leaders.
  62.  *
  63.  * Revision 5.3  1990/09/11  02:41:13  eggert
  64.  * Tune expandline().
  65.  *
  66.  * Revision 5.2  1990/09/04  08:02:21  eggert
  67.  * Count RCS lines better.  Improve incomplete line handling.
  68.  *
  69.  * Revision 5.1  1990/08/29  07:13:56  eggert
  70.  * Add -kkvl.
  71.  * Fix bug when getting revisions to files ending in incomplete lines.
  72.  * Fix bug in comment leader expansion.
  73.  *
  74.  * Revision 5.0  1990/08/22  08:12:47  eggert
  75.  * Don't require final newline.
  76.  * Don't append "checked in with -k by " to logs,
  77.  * so that checking in a program with -k doesn't change it.
  78.  * Don't generate trailing white space for empty comment leader.
  79.  * Remove compile-time limits; use malloc instead.  Add -k, -V.
  80.  * Permit dates past 1999/12/31.  Make lock and temp files faster and safer.
  81.  * Ansify and Posixate.  Check diff's output.
  82.  *
  83.  * Revision 4.8  89/05/01  15:12:35  narten
  84.  * changed copyright header to reflect current distribution rules
  85.  * 
  86.  * Revision 4.7  88/11/08  13:54:14  narten
  87.  * misplaced semicolon caused infinite loop
  88.  * 
  89.  * Revision 4.6  88/08/09  19:12:45  eggert
  90.  * Shrink stdio code size; allow cc -R.
  91.  * 
  92.  * Revision 4.5  87/12/18  11:38:46  narten
  93.  * Changes from the 43. version. Don't know the significance of the
  94.  * first change involving "rewind". Also, additional "lint" cleanup.
  95.  * (Guy Harris)
  96.  * 
  97.  * Revision 4.4  87/10/18  10:32:21  narten
  98.  * Updating version numbers. Changes relative to version 1.1 actually
  99.  * relative to 4.1
  100.  * 
  101.  * Revision 1.4  87/09/24  13:59:29  narten
  102.  * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
  103.  * warnings)
  104.  * 
  105.  * Revision 1.3  87/09/15  16:39:39  shepler
  106.  * added an initializatin of the variables editline and linecorr
  107.  * this will be done each time a file is processed.
  108.  * (there was an obscure bug where if co was used to retrieve multiple files
  109.  *  it would dump)
  110.  * fix attributed to  Roy Morris @FileNet Corp ...!felix!roy
  111.  * 
  112.  * Revision 1.2  87/03/27  14:22:17  jenkins
  113.  * Port to suns
  114.  * 
  115.  * Revision 4.1  83/05/12  13:10:30  wft
  116.  * Added new markers Id and RCSfile; added locker to Header and Id.
  117.  * Overhauled expandline completely() (problem with $01234567890123456789@).
  118.  * Moved trymatch() and marker table to rcskeys.c.
  119.  * 
  120.  * Revision 3.7  83/05/12  13:04:39  wft
  121.  * Added retry to expandline to resume after failed match which ended in $.
  122.  * Fixed truncation problem for $19chars followed by@@.
  123.  * Log no longer expands full path of RCS file.
  124.  * 
  125.  * Revision 3.6  83/05/11  16:06:30  wft
  126.  * added retry to expandline to resume after failed match which ended in $.
  127.  * Fixed truncation problem for $19chars followed by@@.
  128.  * 
  129.  * Revision 3.5  82/12/04  13:20:56  wft
  130.  * Added expansion of keyword Locker.
  131.  *
  132.  * Revision 3.4  82/12/03  12:26:54  wft
  133.  * Added line number correction in case editing does not start at the
  134.  * beginning of the file.
  135.  * Changed keyword expansion to always print a space before closing KDELIM;
  136.  * Expansion for Header shortened.
  137.  *
  138.  * Revision 3.3  82/11/14  14:49:30  wft
  139.  * removed Suffix from keyword expansion. Replaced fclose with ffclose.
  140.  * keyreplace() gets log message from delta, not from curlogmsg.
  141.  * fixed expression overflow in while(c=putc(GETC....
  142.  * checked nil printing.
  143.  *
  144.  * Revision 3.2  82/10/18  21:13:39  wft
  145.  * I added checks for write errors during the co process, and renamed
  146.  * expandstring() to xpandstring().
  147.  *
  148.  * Revision 3.1  82/10/13  15:52:55  wft
  149.  * changed type of result of getc() from char to int.
  150.  * made keyword expansion loop in expandline() portable to machines
  151.  * without sign-extension.
  152.  */
  153.  
  154.  
  155. #include "rcsbase.h"
  156.  
  157. libId(editId, "$Id: rcsedit.c,v 5.11 1991/11/03 01:11:44 eggert Exp $")
  158.  
  159. static void keyreplace P((enum markers,struct hshentry const*,FILE*));
  160.  
  161.  
  162. FILE *fcopy;         /* result file descriptor                */
  163. char const *resultfile;  /* result file name                    */
  164. int locker_expansion;     /* should the locker name be appended to Id val?   */
  165. #if !large_memory
  166.     static RILE *fedit; /* edit file descriptor */
  167.     static char const *editfile; /* edit pathname */
  168. #endif
  169. static unsigned long editline; /* edit line counter; #lines before cursor   */
  170. static long linecorr; /* #adds - #deletes in each edit run.            */
  171.                /*used to correct editline in case file is not rewound after */
  172.                /* applying one delta                                        */
  173.  
  174. #define DIRTEMPNAMES 2
  175. enum maker {notmade, real, effective};
  176. struct buf dirtfname[DIRTEMPNAMES];        /* unlink these when done */
  177. static enum maker volatile dirtfmaker[DIRTEMPNAMES];    /* if these are set */
  178.  
  179.  
  180. #if has_NFS || bad_unlink
  181.     int
  182. un_link(s)
  183.     char const *s;
  184. /*
  185.  * Remove S, even if it is unwritable.
  186.  * Ignore unlink() ENOENT failures; NFS generates bogus ones.
  187.  */
  188. {
  189. #    if bad_unlink
  190.         int e;
  191.         if (unlink(s) == 0)
  192.             return 0;
  193.         e = errno;
  194. #        if has_NFS
  195.             if (e == ENOENT)
  196.                 return 0;
  197. #        endif
  198.         if (chmod(s, S_IWUSR) != 0) {
  199.             errno = e;
  200.             return -1;
  201.         }
  202. #    endif
  203. #    if has_NFS
  204.         return unlink(s)==0 || errno==ENOENT  ?  0  :  -1;
  205. #    else
  206.         return unlink(s);
  207. #    endif
  208. }
  209. #endif
  210.  
  211. #if !has_rename
  212. #  if !has_NFS
  213. #    define do_link(s,t) link(s,t)
  214. #  else
  215.     static int
  216. do_link(s, t)
  217.     char const *s, *t;
  218. /* Link S to T, ignoring bogus EEXIST problems due to NFS failures.  */
  219. {
  220.     struct stat sb, tb;
  221.  
  222.     if (link(s,t) == 0)
  223.         return 0;
  224.     if (errno != EEXIST)
  225.         return -1;
  226.     if (
  227.         stat(s, &sb) == 0  &&
  228.         stat(t, &tb) == 0  &&
  229.         sb.st_ino == tb.st_ino  &&
  230.         sb.st_dev == tb.st_dev
  231.     )
  232.         return 0;
  233.     errno = EEXIST;
  234.     return -1;
  235. }
  236. #  endif
  237. #endif
  238.  
  239.  
  240.     static exiting void
  241. editEndsPrematurely()
  242. {
  243.     fatserror("edit script ends prematurely");
  244. }
  245.  
  246.     static exiting void
  247. editLineNumberOverflow()
  248. {
  249.     fatserror("edit script refers to line past end of file");
  250. }
  251.  
  252.  
  253. #if large_memory
  254.  
  255. #if has_memmove
  256. #    define movelines(s1, s2, n) VOID memmove(s1, s2, (n)*sizeof(Iptr_type))
  257. #else
  258.     static void
  259. movelines(s1, s2, n)
  260.     register Iptr_type *s1;
  261.     register Iptr_type const *s2;
  262.     register unsigned long n;
  263. {
  264.     if (s1 < s2)
  265.         do {
  266.             *s1++ = *s2++;
  267.         } while (--n);