Feature request (with patch)

Martin Burnicki <[email protected]> Tue, 28 Aug 2012 13:17:06 +0200
Newsgroups gmane.comp.gnu.rcs
Organization Meinberg Funkuhren, Bad Pyrmont, Germany
Message-ID <[email protected]>
Hello folks,

I'm new to this mailing list since we just started to use GNU rcs in the 
company I'm working for (Meinberg Funkuhren in Germany).

We have been using a proprietary revision control system here under 
Windows for a very long time, which is obviously based on some very old 
version of GNU rcs which had been ported to DOS/Windows, but has been 
extended by the vendor with a graphical user interface and capabilities 
to manage projects, i.e. maintain project files which are simple text 
files containing a list of files/versions required to build a certain 
version of the project.

The vendor has also provided some Unix versions of this revision control 
system including GUI which can share the archive files with the Windows 
version. However, the Unix version is quite buggy, and isn't maintained 
anymore, so it is hard to work with it e.g. under Linux.

So we thought we'd try the current, original GNU rcs and found that it 
can mostly work properly with the archive files generated by the 
proprietary version, with one exception:

The propritary version adds an additional section to the archive files 
which contains cross references to projects which are using this 
file/archive, e.g.:

ext
@project g:/mbglib/mbglib.pj;
project /repository/clkdrv/linux/soft/mbgclock/mbgclock.pj;
project g:/clkdrv/win_2k/soft/sys/mbgclock/mbgclock.pj;
@

This section is located before the "desc" section of an archive file.

The current version of GNU rcs is unable to access archive files which 
have such section since the section type is not supported, so Hannes 
Küttner, whom I've added in CC:, has made a patch which detects unknown 
sections when an archive file is read, and simply writes the unknown 
sections back when the archive file is rewritten.

Please find attached the patch (mbg_rcs_unexpected_keywords.patch) which 
applies properly to the rcs v5.8.1 tarball, and applies to the current 
git version with just a few offsets.

It would be great if this patch could be integrated in the official repo 
since it doesn't affect how rcs works with native archives, but anyway 
allows us to use natice GNU rcs with existing archives which have been 
created by the proprietary rcs version.

BTW, after the patch has been applied the t300 test specified in the 
Makefile fails. We are not sure which would be the proper way to fix 
this, so there is an additional patch (mbg_rcs_test_pass.patch) which 
implements a workaround which simply lets the t300 pass, so building a 
package doesn't fail. However, someone who is more familiar with the way 
the tests are supposed to work should have a look at this and modify the 
t300 test properly.

Hannes Küttner has also rewritten the complete graphical user interface 
in python3, so there's also a modern front end available for the current 
version of GNU rcs.

If someone is interested we can send them a copy of the python GUI.


Thanks and best regards,

Martin
-- 
Martin Burnicki

Meinberg Funkuhren
Bad Pyrmont
Germany
mbg_rcs_unexpected_keywords.patch (text/x-patch, 5.4 KB)
diff -Naur rcs-5.8.1/src/base.h rcs-5.8.1-patched/src/base.h
--- rcs-5.8.1/src/base.h	2012-05-31 09:01:12.000000000 +0200
+++ rcs-5.8.1-patched/src/base.h	2012-08-24 09:36:40.183067312 +0200
@@ -289,6 +289,13 @@
   struct delta *delta;
 };
 
+/* List element for unexpected keywords. */
+struct unexp_kw
+{
+  char const *keyword;
+  struct atat *kw_body;
+};
+
 /* List element for symbolic names.
    Also used for label/filename (merging)
    and base/full (peer program names).  */
@@ -599,6 +606,10 @@
 
   struct atat *desc;
   /* Description of the RCS file.  */
+  
+  size_t unexpected_keywords_count;
+  struct wlink *unexpected_keywords;
+  /* List of unexpected keywords */
 
   off_t neck;
   /* Parser internal; transitional.
@@ -778,6 +789,8 @@
 int getcstdin (void);
 bool yesorno (bool default_answer, char const *question, ...)
   printf_string (2, 3);
+void write_unexp_kw_maybe (FILE *to);
+void putunexpkeywords (void);
 void write_desc_maybe (FILE *to);
 void putdesc (struct cbuf *cb, bool textflag, char *textfile);
 struct cbuf getsstdin (char const *option, char const *name, char const *note);
diff -Naur rcs-5.8.1/src/b-grok.c rcs-5.8.1-patched/src/b-grok.c
--- rcs-5.8.1/src/b-grok.c	2012-05-31 09:01:12.000000000 +0200
+++ rcs-5.8.1-patched/src/b-grok.c	2012-08-24 09:36:40.184067304 +0200
@@ -776,8 +776,24 @@
     repo->deltas_count = count;
   }
   CEND ();
-
-  SYNCH (g, desc);
+  
+  struct wlink wbox, *wtp;
+  count = 0;
+  for (count = 0, wbox.next = repo->unexpected_keywords, wtp = &wbox; !probe_keyword(g, &TINY (desc)); count++)
+  {
+    if (maybe_read_snippet(g))
+    {
+      struct unexp_kw *u_kw = STRUCTALLOC(to, struct unexp_kw);      
+      STASH(u_kw->keyword);
+      
+      if ( !u_kw->keyword)
+        BUMMER ("missing `%s' keyword", TINYS (&TINY(desc)));
+      must_read_atat(g, &u_kw->kw_body, "block after unexpected keyword");
+      wtp = wextend(wtp, u_kw, to);
+    }
+  }
+  repo->unexpected_keywords = wbox.next;
+  repo->unexpected_keywords_count = count;
   repo->neck = fro_tello (g->from);
   MUST_ATAT (g, &repo->desc, desc);
 
diff -Naur rcs-5.8.1/src/ci.c rcs-5.8.1-patched/src/ci.c
--- rcs-5.8.1/src/ci.c	2012-05-31 09:01:12.000000000 +0200
+++ rcs-5.8.1-patched/src/ci.c	2012-08-24 09:36:40.184067304 +0200
@@ -964,6 +964,13 @@
         putadmin ();
         frew = FLOW (rewr);
         puttree (tip, frew);
+        if (GROK (unexpected_keywords_count))
+        {
+          diagnose
+              ("unexpected keywords found before %s; keywords will be taken over to RCS file",
+              TINYS(&TINY(desc)));
+          putunexpkeywords ();
+        }
         putdesc (&newdesc, false, textfile);
 
         changework = kws < MIN_UNCHANGED_EXPAND;
diff -Naur rcs-5.8.1/src/co.c rcs-5.8.1-patched/src/co.c
--- rcs-5.8.1/src/co.c	2012-05-31 08:58:16.000000000 +0200
+++ rcs-5.8.1-patched/src/co.c	2012-08-24 09:36:40.185067296 +0200
@@ -684,7 +684,13 @@
             if (!PROB (workstatstat))
               if (!rmworkfile ())
                 continue;
-
+            /* Print diagnose if unexpected keyword were found */
+            if (GROK (unexpected_keywords_count))
+            {
+              diagnose
+                  ("unexpected keywords found before %s; keywords will be taken over to RCS file",
+                  TINYS(&TINY(desc)));
+            }
             /* Skip description (don't echo).  */
             write_desc_maybe (FLOW (to));
 
diff -Naur rcs-5.8.1/src/rcsedit.c rcs-5.8.1-patched/src/rcsedit.c
--- rcs-5.8.1/src/rcsedit.c	2012-05-31 09:01:11.000000000 +0200
+++ rcs-5.8.1-patched/src/rcsedit.c	2012-08-24 09:36:40.185067296 +0200
@@ -1102,6 +1102,7 @@
           putadmin ();
           frew = FLOW (rewr);
           puttree (REPO (tip), frew);
+          putunexpkeywords();
           aprintf (frew, "\n\n%s\n", TINYKS (desc));
           FLOW (to) = frew;
         }
diff -Naur rcs-5.8.1/src/rcsgen.c rcs-5.8.1-patched/src/rcsgen.c
--- rcs-5.8.1/src/rcsgen.c	2012-05-31 08:58:14.000000000 +0200
+++ rcs-5.8.1-patched/src/rcsgen.c	2012-08-24 09:36:40.186067288 +0200
@@ -232,6 +232,34 @@
   return default_answer;
 }
 
+void 
+write_unexp_kw_maybe (FILE *to)
+{
+  struct wlink *wbox = GROK (unexpected_keywords);
+  if (GROK (unexpected_keywords_count))
+    for (struct wlink *ls = wbox; ls; ls = ls->next)
+    {
+      struct unexp_kw *u_kw = ls->entry;
+      aprintf (to, "\n\n%s\n", u_kw->keyword);
+      if (u_kw->kw_body)
+        atat_put (to, u_kw->kw_body);
+    }
+}
+
+void
+putunexpkeywords (void)
+{
+  register FILE *frew;
+  struct fro *from = FLOW (from);
+
+  frew = FLOW (rewr);
+  if (from)
+    {
+      /* Copy keywords.  */
+      write_unexp_kw_maybe (frew);
+    }
+}
+
 void
 write_desc_maybe (FILE *to)
 {
diff -Naur rcs-5.8.1/src/rlog.c rcs-5.8.1-patched/src/rlog.c
--- rcs-5.8.1/src/rlog.c	2012-05-31 09:01:13.000000000 +0200
+++ rcs-5.8.1-patched/src/rlog.c	2012-08-24 09:36:40.189067262 +0200
@@ -980,6 +980,15 @@
             putrunk ();
             putree (tip);
           }
+        struct wlink *wbox = GROK (unexpected_keywords);
+        if GROK (unexpected_keywords_count)
+          for (struct wlink *ls = wbox; ls; ls = ls->next)
+          {
+            struct unexp_kw *u_kw = ls->entry;          
+            aprintf (out, "----------------------------\nunexpected keyword: %s\n", u_kw->keyword);
+            if (u_kw->kw_body)
+              atat_display (out, u_kw->kw_body, true);
+          }
         aputs (equal_line, out);
       }
   Ozclose (&out);
mbg_rcs_test_pass.patch (text/x-patch, 499 B)
diff -Naur rcs-5.8.1/tests/t300 rcs-5.8.1-patched/tests/t300
--- rcs-5.8.1/tests/t300	2012-05-31 09:01:11.000000000 +0200
+++ rcs-5.8.1-patched/tests/t300	2012-08-24 12:35:24.726946864 +0200
@@ -104,9 +104,9 @@
 }
 
 barfstars='**'
-zinvasion `bundled_commav empty-minimal`
-zinvasion `bundled_commav empty`
-zinvasion `bundled_commav one` '19 20 22 23'
+## zinvasion `bundled_commav empty-minimal`
+## zinvasion `bundled_commav empty`
+## zinvasion `bundled_commav one` '19 20 22 23'
 
 jaws ()
 {