[net.bugs] fixes to refer

kelem@aero.ARPA (Steve Kelem) (12/20/85)

These are fixes to the 'refer' program (used in conjunction with 'troff').
This program has a problem with accents in last names.
On page 6 of the documentation, ("Refer - A Bibliography System", Bill Tuthill,
Computing Services, UCB) it states that "interpolated strings (such as accent
marks) must have two backslashes, so they can pass through copy mode intact.
Assume that a database has the following entry:

%A Carlo H. Se\\*'quin
%T Generalized IC Layout
%D January 6, 1982
%I Computer Science Division, Electrical Engineering and Computer Sciences,
University of California, Berkeley
%C Berkeley, California

Bug #1:
    The -l option (labeled references) causes:
a) the citation to print as [Se\*'quin1982] (one too many backslashes causes
it not to be interpolated),
b) the reference to print properly (the right number of backslashes),
but causes c) the reference tag to print both "Se" and "quin" at the left
margin (overstriking and making it almost illegible) (not enough backslashes to
prevent the interpolation of \*' until the correct moment - the string gets
copied one too many times).

Bug #3:
    The option -l4,2 (labels with 1st four characters of name,
last 2 digits of the year), causes the citation to print as [Se\82]
(the 4 characters are "Se\\") and the reference tag overprints "Se" and "82".

The following shar file creates two diff files that can be used to update
/usr/src/usr.bin/refer/{Makefile,refer5.c}.  Use the patch program to apply
the differences (this will copy the original files to Makefile.orig and
refer5.c.orig and give you the two new, corrected files).

Steve Kelem

#!/bin/sh-----cut here-----cut here-----cut here-----cut here-----
# shar: Shell Archiver
#       Run the following text with /bin/sh to create:
#       Makefile.diff # refer5.diff
cat - << \SHAR_EOF > Makefile.diff
*** Makefile.old        Thu Dec 19 15:11:11 1985
--- Makefile    Thu Dec 19 15:11:30 1985
***************
*** 1,4
! #     @(#)Makefile    4.4     (Berkeley)      12/19/85
  #
  DESTDIR=
  CFLAGS = -O

--- 1,4 -----
! #     @(#)Makefile    4.4.1.1 (Berkeley)      12/19/85
  #
  DESTDIR=
  CFLAGS = -O
***************
*** 2,7
  #
  DESTDIR=
  CFLAGS = -O
     
  all:  mkey inv hunt refer addbib lookbib sortbib
     

--- 2,8 -----
  #
  DESTDIR=
  CFLAGS = -O
+ LDFLAGS = -O
     
  all:  mkey inv hunt refer addbib lookbib sortbib
     
***************
*** 6,12
  all:  mkey inv hunt refer addbib lookbib sortbib
     
  mkey: mkey1.o mkey2.o mkey3.o deliv2.o
!       cc mkey?.o deliv2.o -o mkey
  inv: inv1.o inv2.o inv3.o inv5.o inv6.o deliv2.o
        cc inv?.o deliv2.o -o inv
  hunt: hunt1.o hunt2.o hunt3.o hunt5.o hunt6.o hunt7.o glue5.o

--- 7,13 -----
  all:  mkey inv hunt refer addbib lookbib sortbib
     
  mkey: mkey1.o mkey2.o mkey3.o deliv2.o
!       $(CC) $(LDFLAGS) -o mkey mkey?.o deliv2.o
  inv: inv1.o inv2.o inv3.o inv5.o inv6.o deliv2.o
        $(CC) $(LDFLAGS) -o inv inv?.o deliv2.o
  hunt: hunt1.o hunt2.o hunt3.o hunt5.o hunt6.o hunt7.o glue5.o
***************
*** 8,14
  mkey: mkey1.o mkey2.o mkey3.o deliv2.o
        cc mkey?.o deliv2.o -o mkey
  inv: inv1.o inv2.o inv3.o inv5.o inv6.o deliv2.o
!       cc inv?.o deliv2.o -o inv
  hunt: hunt1.o hunt2.o hunt3.o hunt5.o hunt6.o hunt7.o glue5.o
  hunt: refer3.o hunt9.o shell.o deliv2.o hunt8.o glue4.o tick.o
        cc hunt?.o refer3.o glue5.o glue4.o shell.o deliv2.o tick.o -o hunt

--- 9,15 -----
  mkey: mkey1.o mkey2.o mkey3.o deliv2.o
        $(CC) $(LDFLAGS) -o mkey mkey?.o deliv2.o
  inv: inv1.o inv2.o inv3.o inv5.o inv6.o deliv2.o
!       $(CC) $(LDFLAGS) -o inv inv?.o deliv2.o
  hunt: hunt1.o hunt2.o hunt3.o hunt5.o hunt6.o hunt7.o glue5.o
  hunt: refer3.o hunt9.o shell.o deliv2.o hunt8.o glue4.o tick.o
        $(CC) $(LDFLAGS) -o hunt hunt?.o refer3.o glue5.o glue4.o shell.o \
***************
*** 11,17
        cc inv?.o deliv2.o -o inv
  hunt: hunt1.o hunt2.o hunt3.o hunt5.o hunt6.o hunt7.o glue5.o
  hunt: refer3.o hunt9.o shell.o deliv2.o hunt8.o glue4.o tick.o
!       cc hunt?.o refer3.o glue5.o glue4.o shell.o deliv2.o tick.o -o hunt
     
  glue3.o: refer..c
  hunt2.o: refer..c

--- 12,19 -----
        $(CC) $(LDFLAGS) -o inv inv?.o deliv2.o
  hunt: hunt1.o hunt2.o hunt3.o hunt5.o hunt6.o hunt7.o glue5.o
  hunt: refer3.o hunt9.o shell.o deliv2.o hunt8.o glue4.o tick.o
!       $(CC) $(LDFLAGS) -o hunt hunt?.o refer3.o glue5.o glue4.o shell.o \
!           deliv2.o tick.o
     
  glue3.o: refer..c
  hunt2.o: refer..c
***************
*** 26,32
  refer: glue1.o refer1.o refer2.o refer4.o refer5.o refer6.o mkey3.o
  refer: refer7.o refer8.o hunt2.o hunt3.o deliv2.o hunt5.o hunt6.o hunt8.o
  refer: glue3.o hunt7.o hunt9.o glue2.o glue4.o glue5.o refer0.o shell.o
!       cc -i glue?.o refer[01245678].o hunt[2356789].o mkey3.o shell.o deliv2.o -o refer
     
  addbib: addbib.o
        cc addbib.o -o addbib

--- 28,35 -----
  refer: glue1.o refer1.o refer2.o refer4.o refer5.o refer6.o mkey3.o
  refer: refer7.o refer8.o hunt2.o hunt3.o deliv2.o hunt5.o hunt6.o hunt8.o
  refer: glue3.o hunt7.o hunt9.o glue2.o glue4.o glue5.o refer0.o shell.o
!       $(CC) $(LDFLAGS) -o refer glue?.o refer[01245678].o hunt[2356789].o \
!           mkey3.o shell.o deliv2.o
     
  addbib: addbib.o
        $(CC) $(LDFLAGS) -o addbib addbib.o
***************
*** 29,35
        cc -i glue?.o refer[01245678].o hunt[2356789].o mkey3.o shell.o deliv2.o -o refer
     
  addbib: addbib.o
!       cc addbib.o -o addbib
  lookbib: lookbib.o
        cc lookbib.o -o lookbib
  sortbib: sortbib.o

--- 32,38 -----
            mkey3.o shell.o deliv2.o
     
  addbib: addbib.o
!       $(CC) $(LDFLAGS) -o addbib addbib.o
  lookbib: lookbib.o
        $(CC) $(LDFLAGS) -o lookbib lookbib.o
  sortbib: sortbib.o
***************
*** 31,37
  addbib: addbib.o
        cc addbib.o -o addbib
  lookbib: lookbib.o
!       cc lookbib.o -o lookbib
  sortbib: sortbib.o
        cc sortbib.o -o sortbib
     

--- 34,40 -----
  addbib: addbib.o
        $(CC) $(LDFLAGS) -o addbib addbib.o
  lookbib: lookbib.o
!       $(CC) $(LDFLAGS) -o lookbib lookbib.o
  sortbib: sortbib.o
        $(CC) $(LDFLAGS) -o sortbib sortbib.o
     
***************
*** 33,39
  lookbib: lookbib.o
        cc lookbib.o -o lookbib
  sortbib: sortbib.o
!       cc sortbib.o -o sortbib
     
  install: all
        install -s mkey $(DESTDIR)/usr/lib/refer

--- 36,42 -----
  lookbib: lookbib.o
        $(CC) $(LDFLAGS) -o lookbib lookbib.o
  sortbib: sortbib.o
!       $(CC) $(LDFLAGS) -o sortbib sortbib.o
     
  install: all
        install -s mkey $(DESTDIR)/usr/lib/refer
***************
*** 50,56
        rm -f refer inv hunt mkey addbib lookbib sortbib *.o
     
  whatabout: what1.o what2.o what3.o what4.o shell.o mkey3.o
!       cc what?.o shell.o mkey3.o  -o whatabout
  deliv: deliv1.o deliv2.o
        cc deliv?.o  -o deliv
  refpart: refer0.o refer1.o refer2.o refer3.o refer4.o refer5.o

--- 53,59 -----
        rm -f refer inv hunt mkey addbib lookbib sortbib *.o
     
  whatabout: what1.o what2.o what3.o what4.o shell.o mkey3.o
!       $(CC) $(LDFLAGS) -o whatabout what?.o shell.o mkey3.o
  deliv: deliv1.o deliv2.o
        $(CC) $(LDFLAGS) -o deliv deliv?.o
  refpart: refer0.o refer1.o refer2.o refer3.o refer4.o refer5.o
***************
*** 52,58
  whatabout: what1.o what2.o what3.o what4.o shell.o mkey3.o
        cc what?.o shell.o mkey3.o  -o whatabout
  deliv: deliv1.o deliv2.o
!       cc deliv?.o  -o deliv
  refpart: refer0.o refer1.o refer2.o refer3.o refer4.o refer5.o
  refpart: refer6.o refer7.o refer8.o deliv2.o glue4.o
        cc refer?.o deliv2.o glue4.o  -o refpart

--- 55,61 -----
  whatabout: what1.o what2.o what3.o what4.o shell.o mkey3.o
        $(CC) $(LDFLAGS) -o whatabout what?.o shell.o mkey3.o
  deliv: deliv1.o deliv2.o
!       $(CC) $(LDFLAGS) -o deliv deliv?.o
  refpart: refer0.o refer1.o refer2.o refer3.o refer4.o refer5.o
  refpart: refer6.o refer7.o refer8.o deliv2.o glue4.o
        $(CC) $(LDFLAGS) -o refpart refer?.o deliv2.o glue4.o
***************
*** 55,58
        cc deliv?.o  -o deliv
  refpart: refer0.o refer1.o refer2.o refer3.o refer4.o refer5.o
  refpart: refer6.o refer7.o refer8.o deliv2.o glue4.o
!       cc refer?.o deliv2.o glue4.o  -o refpart

--- 58,61 -----
        $(CC) $(LDFLAGS) -o deliv deliv?.o
  refpart: refer0.o refer1.o refer2.o refer3.o refer4.o refer5.o
  refpart: refer6.o refer7.o refer8.o deliv2.o glue4.o
!       $(CC) $(LDFLAGS) -o refpart refer?.o deliv2.o glue4.o
SHAR_EOF
cat - << \SHAR_EOF > refer5.diff
*** refer5.c.old        Thu Dec 19 15:13:16 1985
--- refer5.c    Thu Dec 19 15:13:38 1985
***************
*** 1,5
  #ifndef lint
! static char *sccsid = "@(#)refer5.c   4.2 (Berkeley) 7/18/83";
  #endif
     
  #include "refer..c"

--- 1,5 -----
  #ifndef lint
! static char *sccsid = "@(#)refer5.c   4.2.1.3 (Berkeley) 12/18/85";
  #endif
     
  #include "refer..c"
***************
*** 33,40
                                sprintf(t, "%s", fpar(nf,flds,t1,keywant,1,0));
                        if (science && t[0] == 0) {
                                sd = fpar(nf, flds, t2, 'D', 1, 0);
!                               sprintf(t, "%s, %s", fpar(nf,flds,t1,'A',1,0),
!                                       sd);
                        }
                        else if (t[0] == 0) {
                                sprintf(format,

--- 33,39 -----
                sprintf(t, "%s", fpar(nf,flds,t1,keywant,1,0));
            if (science && t[0] == 0) {
                sd = fpar(nf, flds, t2, 'D', 1, 0);
!               sprintf(t, "%s, %s", fpar(nf,flds,t1,'A',1,0), sd);
            }
            else if (t[0] == 0) {
                /* length of author field, counting troff characters */
***************
*** 37,42
                                        sd);
                        }
                        else if (t[0] == 0) {
                                sprintf(format,
                                        nmlen>0 ? "%%.%ds%%s" : "%%s%%s",
                                        nmlen);

--- 36,83 -----
                sprintf(t, "%s, %s", fpar(nf,flds,t1,'A',1,0), sd);
            }
            else if (t[0] == 0) {
+               /* length of author field, counting troff characters */
+               int eff_len, real_len;
+               char *auth_ptr;
+               /* get the author field in t1 */
+               fpar(nf,flds,t1,'A',1,0);
+               /* look for troff charcters */
+               if (nmlen <= 0)
+                   real_len = nmlen;
+               else {
+                   eff_len = real_len = 0;
+                   auth_ptr = t1 -1;
+                   while (* ++auth_ptr && eff_len < nmlen ) {
+                       /* check for troff characters */
+                       if (*auth_ptr == '\\') { /* an escape sequence*/
+                           if (* (auth_ptr+1) == '\\')
+                               auth_ptr ++; /* copy mode - skip backslash */
+                           if (* ++auth_ptr == '*') { /* \*x or \\*x */
+                               /* string - skip asterisk */
+                               if ( * ++auth_ptr == '\'' || * auth_ptr == '`'
+                                   || * auth_ptr == '^'  || * auth_ptr == '~'
+                                   || * auth_ptr == ','  || * auth_ptr == ':'
+                                   || * auth_ptr == ';')
+                                   eff_len--;  /* don't count accents */
+                               else if (* auth_ptr == '(')
+                                   auth_ptr += 2; /* 2-character string name */
+                               }
+                           else if (* auth_ptr == '0' || * auth_ptr == '&'
+                                   || * auth_ptr == 'd' || * auth_ptr == 'r'
+                                   || * auth_ptr == 'u')
+                               eff_len --; /* don't count \0 (0-width space) */
+                           else if (* auth_ptr == '(' )
+                               auth_ptr += 2;  /* two-character name */
+                           else if (* auth_ptr == 'z')
+                               auth_ptr ++;    /* print char without spacing */
+                           }
+                       eff_len ++;
+                   }
+                   real_len = auth_ptr-t1;
+               }
+ #if EBUG
+               fprintf(stderr, "name %s has length %d\n", t1, real_len);
+ #endif
                sprintf(format,
                    nmlen>0 ? "%%.%ds%%s" : "%%s%%s",
                    real_len);
***************
*** 39,45
                        else if (t[0] == 0) {
                                sprintf(format,
                                        nmlen>0 ? "%%.%ds%%s" : "%%s%%s",
!                                       nmlen);
                                /* format is %s%s for default labels */
                                /* or %.3s%s eg if wanted */
                                sd = fpar(nf, flds, t2, 'D', 1, 0);

--- 80,86 -----
  #endif
                sprintf(format,
                    nmlen>0 ? "%%.%ds%%s" : "%%s%%s",
!                   real_len);
                /* format is %s%s for default labels */
                /* or %.3s%s eg if wanted */
                sd = fpar(nf, flds, t2, 'D', 1, 0);
***************
*** 51,58
                                        if (sd < sdb)
                                                sd = sdb;
                                }
!                               sprintf(t, format, fpar(nf,flds,t1,'A',1,0),
!                                       sd);
                        }
                        if (keywant) {
                                addon = 0;

--- 92,98 -----
                    if (sd < sdb)
                        sd = sdb;
                }
!               sprintf(t, format, t1, sd);
            }
            if (keywant) {
                addon = 0;
***************
*** 81,87
        if (another && (strcmp(".[\n", sd) != SAME))
                fprintf(stderr, "File %s line %d: punctuation ignored from: %s",
                        Ifile, Iline, sd);
!       strcat(sig, t);
  #if EBUG
        fprintf(stderr, "sig is now %s leng %d\n",sig,strlen(sig));
  #endif

--- 121,134 -----
      if (another && (strcmp(".[\n", sd) != SAME))
        fprintf(stderr, "File %s line %d: punctuation ignored from: %s",
            Ifile, Iline, sd);
! /*     strcat(sig, t); */
!     {char * str, *dest;
!     str = t-1; dest = sig+strlen(sig);
!     while (*++str) {  /* copy the signal, undoubling the backslashes */
!       if (*str == '\\' && *++str == '\\');
!       *dest++ = *str;
!       }
!     }
  #if EBUG
      fprintf(stderr, "sig is now %s leng %d\n",sig,strlen(sig));
  #endif
***************
*** 138,145
                }
        }
        if (bare < 2)
!               if (nf > 0)
!                       fprintf(fo,".ds [F %s%c",t,sep);
        if (bare > 0)
                flout();
  #if EBUG

--- 185,204 -----
        }
      }
      if (bare < 2)
!       if (nf > 0) {
!           char * str;
!           str = t;
! /*        fprintf(fo,".ds [F %s%c",t,sep); */
!           fprintf(fo,".ds [F ");
!           while (*str) { /* double backslashes for deferred interpolation */
!               if (*str == '\\')
!                   fputc('\\', fo);
!               fputc(*str++, fo);
!               }
!           if (sep == '\\')
!               fputc('\\', fo);
!           fputc(sep, fo);
!           }
      if (bare > 0)
        flout();
  #if EBUG
***************
*** 168,174
                                mycpy2(out, p, 20);
                                return(out);
                        }
!                       /* if its not 'L' then use just the last word */
                        s = p = flds[i]+2;
                        if (c != 'L') {
                            for(; *p; p++);

--- 227,233 -----
                                mycpy2(out, p, 20);
                                return(out);
                        }
!                       /* if it's not 'L' then use just the last word */
                        s = p = flds[i]+2;
                        if (c != 'L') {
                            for(; *p; p++);
SHAR_EOF