summaryrefslogtreecommitdiff
path: root/biblio/tib/src
diff options
context:
space:
mode:
Diffstat (limited to 'biblio/tib/src')
-rw-r--r--biblio/tib/src/Makefile55
-rw-r--r--biblio/tib/src/locate.c217
-rw-r--r--biblio/tib/src/makekey.c74
-rw-r--r--biblio/tib/src/seek.c73
-rw-r--r--biblio/tib/src/streams.c136
-rw-r--r--biblio/tib/src/tib.c775
-rw-r--r--biblio/tib/src/tibargs.c1876
-rw-r--r--biblio/tib/src/tibdex.c239
-rw-r--r--biblio/tib/src/tiblist.c219
-rw-r--r--biblio/tib/src/tiblook.c171
10 files changed, 3835 insertions, 0 deletions
diff --git a/biblio/tib/src/Makefile b/biblio/tib/src/Makefile
new file mode 100644
index 0000000000..a215681042
--- /dev/null
+++ b/biblio/tib/src/Makefile
@@ -0,0 +1,55 @@
+CC = cc
+CFLAGS = -O
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+DEXo = tibdex.o streams.o makekey.o
+DEXc = tibdex.c streams.c makekey.c
+LOOKo = tiblook.o locate.o seek.o streams.o makekey.o
+LOOKc = tiblook.c locate.c seek.c streams.c makekey.c
+TIBo = tib.o tibargs.o locate.o seek.o streams.o makekey.o
+TIBc = tib.c tibargs.c locate.c seek.c streams.c makekey.c
+LISTo = tiblist.o tibargs.o streams.o makekey.o
+LISTc = tiblist.c tibargs.c streams.c makekey.c
+
+SRCS = \
+ tib.c \
+ tibargs.c \
+ seek.c \
+ tib.h \
+ tibdex.c \
+ tiblist.c \
+ locate.c \
+ tiblook.c \
+ makekey.c \
+ streams.c
+
+all: tibdex tiblook tiblist tib
+
+tibdex: $(DEXo)
+ $(CC) $(CFLAGS) $(DEXo) -o tibdex
+
+tiblook: $(LOOKo)
+ $(CC) $(CFLAGS) $(LOOKo) -o tiblook
+
+tib: $(TIBo)
+ $(CC) $(CFLAGS) $(TIBo) -o tib
+
+tiblist: $(LISTo)
+ $(CC) $(CFLAGS) $(LISTo) -o tiblist
+
+tib.o: tib.h
+tibargs.o: tib.h
+tiblist.o: tib.h
+tibdex.o: tib.h
+locate.o: tib.h
+makekey.o: tib.h
+
+clean:
+ rm -f tib.o tibargs.o tiblist.o tibdex.o tiblook.o
+ rm -f locate.o makekey.o streams.o seek.o
+ rm -f tib.h
+
+veryclean: clean
+ rm -f tib tibdex tiblist tiblook
diff --git a/biblio/tib/src/locate.c b/biblio/tib/src/locate.c
new file mode 100644
index 0000000000..fdd117d9e3
--- /dev/null
+++ b/biblio/tib/src/locate.c
@@ -0,0 +1,217 @@
+#include "stdio.h"
+#include "ctype.h"
+#include "tib.h"
+
+static struct reftype{
+ char reffile[MAXSTR];
+ long int start, length;
+ };
+
+char *malloc();
+char *rindex();
+char *stripkeys();
+int fetchref();
+
+/* locate(keys, name, max_klen, common):
+ Returns a string containing all references pointed to by name
+ that contain all keys in keys. Common is name of common word file.
+ Pointer returned comes from malloc. Use free to return storage.
+ NB A zero length string returned if nothing is found.
+ A NULL pointer indicates an error accessing the file "name".
+*/
+char *locate(keys,name,max_klen,common)
+char *keys, *name, *common;
+int max_klen; /* max key length */
+{ static char oldname[MAXSTR] = ""; /* oldname is name of stream index */
+ static FILE *index = NULL;
+ static long int i_size; /* size of index */
+ static char oldtext[MAXSTR]; /* oldtext is the path to stream */
+ static FILE *text = NULL; /* text. if it is a relative */
+ static int pathlen; /* path, it is relative to index */
+ /* directory. */
+ /* oldname[0..pathlen-1] is index */
+ /* directory */
+ int len;
+ char key[MAXSTR]; /* refs[i] is a line of index for */
+ struct reftype refs[MAXREFS]; /* all keys up to key */
+
+ int refcnt, copied, comp; /* refcnt = # of refs */
+ /* copied = # of refs copied */
+ /* comp = # of refs compared */
+ struct reftype ref;
+ char str[MAXSTR];
+ int more;
+
+ long int ans;
+ int i,j;
+ unsigned total;
+ char *allrefs, *next; /* all refs (separated by null line)*/
+ char *p;
+
+ /* open index */
+ if (strcmp(oldname,name)!=0)
+ { if (index) fclose(index);
+ if (text) fclose(text);
+ strcpy(oldname,name);
+ strcpy(oldtext,"");
+ /* determine pathlen */
+ p= rindex(oldname, '/');
+ if (p!=NULL) pathlen= p-oldname+1;
+ else pathlen= 0;
+
+ index= fopen(oldname,"r");
+ if (index==NULL)
+ { fprintf(stderr, "locate: cannot open %s\n", oldname);
+ strcpy(oldname, "");
+ return(NULL);
+ }
+ else
+ { fseek(index,0L,2); /* seeks last newline */
+ i_size= ftell(index);
+ }
+
+ }
+
+ /* load references to first key */
+ keys= stripkeys(keys,key, max_klen, common);
+ if (*key==NULL)
+ { fprintf(stderr,"locate: no keys for citation\n");
+ allrefs = malloc(1);
+ if (allrefs==NULL)
+ { fprintf(stderr,
+ "locate: insufficient space for references\n");
+ clnup();
+ exit(1);
+ }
+ *allrefs= NULL;
+ return(allrefs);
+ }
+ len= strlen(key);
+ strcat(key," ");
+ alpha_seek(index, key, i_size, 0);
+ key[len]= NULL; /* strip blank off */
+
+ refcnt= 0;
+ fscanf(index,"%s ", str);
+ if (strcmp(str,key) == 0)
+ { str[0]= NULL;
+ while (refcnt < MAXREFS && fetchref(index, str, &ref) )
+ { refs[refcnt]= ref;
+ refcnt++;
+ }
+ }
+
+ if (refcnt==MAXREFS)
+ fprintf(stderr,
+ "locate: first key (%s) matched too many refs\n", key);
+
+ /* intersect the reference sets for remaining keys with first set */
+ while (*keys!=NULL)
+ { keys= stripkeys(keys, key, max_klen, common);
+ if (*key==NULL) continue;
+
+ len= strlen(key);
+ strcat(key," ");
+ alpha_seek(index, key, i_size, 0);
+ key[len]= NULL;
+
+ fscanf(index,"%s ", str);
+ if (strcmp(str,key) != 0) refcnt= 0; /* no matching refs */
+
+ copied= 0; comp= 0; more= fetchref(index, str, &ref);
+ while (comp < refcnt && more)
+ { /* ans= ref-refs[comp] */
+ ans= strcmp(ref.reffile, refs[comp].reffile);
+ if (ans==0) ans= ref.start-refs[comp].start;
+ if (ans==0) ans= ref.length-refs[comp].length;
+ if (ans<0) more= fetchref(index, str, &ref);
+ if (ans==0) { refs[copied]= refs[comp]; comp++; copied++;
+ more= fetchref(index, str, &ref);}
+ if (ans>0) comp++;
+ }
+
+ refcnt= copied;
+ }
+
+ total= 0;
+ for (i=0; i<refcnt; i++) total += refs[i].length+1;
+
+ allrefs= malloc(total+1);
+ if (allrefs==NULL)
+ { fprintf(stderr, "locate: insufficient space for references\n");
+ clnup();
+ exit(1);
+ }
+
+ /* copy refs into allrefs */
+ next= allrefs;
+ for (i=0; i<refcnt; i++)
+ { /* open text */
+ if (strcmp(oldtext,refs[i].reffile) != 0)
+ { strcpy(oldtext,refs[i].reffile);
+ if (oldtext[0]=='/')
+ { /* absolute path */
+ strcpy(str,oldtext);
+ } else
+ { /* relative name */
+ strncpy(str, oldname, pathlen); str[pathlen]= NULL;
+ strcat(str, oldtext);
+ }
+ if (text) fclose(text);
+ text= fopen(str, "r");
+ if (text==NULL)
+ { fprintf(stderr, "locate: cannot open %s\n", str);
+ strcpy(oldtext, "");
+ return(NULL);
+ }
+ }
+ fseek(text, refs[i].start, 0);
+ for (j=0; j<refs[i].length; j++) *next++ = getc(text);
+ *next++ = '\n';
+ }
+ *next = NULL;
+ return(allrefs);
+}
+
+
+
+/* stripkeys(line,key,max_klen, common):
+ assigns to key the first key in line
+ and returns a pointer to the position following the key
+*/
+char *stripkeys(line,key,max_klen,common)
+char *line, *key;
+int max_klen;
+char *common;
+{ char *p;
+
+ do
+ { while (isspace(*line)) line++;
+
+ p= key;
+ while (*line!=NULL && !isspace(*line))
+ { *p++ = *line++;
+ }
+ *p= NULL;
+
+ makekey(key, max_klen, common);
+ } while (*key==NULL && *line!=NULL);
+ return(line);
+}
+
+/* read a reference pair from stream into *ref. if file not given,
+ use oldfile. return 1 if pair found, 0 ow.
+*/
+int fetchref(stream, oldfile, ref)
+FILE *stream;
+char *oldfile;
+struct reftype *ref;
+{ char cntl;
+
+ fscanf(stream, "%c", &cntl);
+ if (cntl=='\n') {return (0);}
+ if (cntl==':') fscanf(stream, "%s", oldfile);
+ strcpy(ref->reffile, oldfile);
+ fscanf(stream, "%D/%D", &ref->start, &ref->length);
+ return(1);
+}
diff --git a/biblio/tib/src/makekey.c b/biblio/tib/src/makekey.c
new file mode 100644
index 0000000000..4940fd60c3
--- /dev/null
+++ b/biblio/tib/src/makekey.c
@@ -0,0 +1,74 @@
+#include "stdio.h"
+#include "ctype.h"
+#include "tib.h"
+
+char commlist[MAXCOMM]= /* list of strings of common words */
+ "";
+int firsttime = 1;
+
+/* makekey(p,max_klen,common): compresses *p into a key
+ folds upper to lower case. ignores non-alphanumeric
+ drops keys of length <= 1.
+ drops words in common (name of file of words, one per line)
+ (first call determines common for all later calls)
+*/
+makekey(p,max_klen,common)
+char *p;
+int max_klen; /* max key length */
+char *common;
+{ register char *from, *to, *stop;
+
+ if (firsttime) {firsttime= 0; load_comm(common); }
+
+ from= p; to= p; stop= max_klen+p;
+ while (*from != NULL && to < stop)
+ { if (islower(*from)) *to++ = *from++;
+ else if (isdigit(*from)) *to++ = *from++;
+ else if (isupper(*from)) { *to++ = tolower(*from); from++; }
+ else from++;
+ }
+ *to= NULL;
+
+ if (to<=p+1 ||
+ lookup(commlist, p) ) *p= NULL;
+}
+
+/* list is a string of null terminated strings, final string is null.
+ p is a null terminated string.
+ return 1 if p is a string in list, 0 ow.
+*/
+int lookup(list,p)
+char *list, *p;
+{ int len;
+ len= strlen(list);
+ while (len!=0 && strcmp(list,p)!=0)
+ { list += (len+1);
+ len= strlen(list);
+ }
+ return(len!=0);
+}
+
+/* read file common into commlist
+*/
+load_comm(common)
+char *common;
+{ FILE *commfile; /* stream of common words */
+ char *p, *stop;
+ commfile= fopen(common,"r");
+ if (commfile==NULL) fprintf(stderr, "cannot open '%s'\n", common);
+ else
+ { /* read commfile into commlist */
+ p= commlist; stop= commlist+MAXCOMM-1;
+ while (p<stop && ((*p= getc(commfile))!=EOF))
+ { if (*p=='\n') *p= NULL;
+ p++;
+ }
+ if (*p==EOF) *p= NULL;
+ else
+ { fprintf(stderr, "invert: too many common words\n");
+ commlist[0]= NULL;
+ }
+ fclose(commfile);
+ }
+}
+
diff --git a/biblio/tib/src/seek.c b/biblio/tib/src/seek.c
new file mode 100644
index 0000000000..71479325fd
--- /dev/null
+++ b/biblio/tib/src/seek.c
@@ -0,0 +1,73 @@
+#include "stdio.h"
+#include "ctype.h"
+#include "tib.h"
+#define nexttry ((high+low)/2)
+#define pos(x) fseek(stream,x,0)
+
+long int nextrecord(), recsize(), nextline();
+
+/* alpha_seek(stream, word, s_size, fold)
+ seeks the first line in stream that is at least word.
+ assumes that stream is a sorted file of lines. (last char must be \n)
+ if fold, assumes that word is lowercase and folds stream to lowercase.
+ s_size = size of stream
+ returns 1 if word = line, 0 o.w.
+*/
+int alpha_seek(stream, word, s_size, fold)
+FILE *stream;
+char *word;
+long int s_size;
+int fold;
+{ long int high, low, mid; /* point to beginning of a line in stream */
+ int ans; /* line(low) < word <= line(high) */
+ char line[MAXSTR];
+
+
+ /* initialize low (return if first line >= word) */
+ low= 0L;
+ pos(low); getline(stream, line);
+ if (fold) foldline(line);
+ ans= strcmp(line,word);
+
+ if ( ans >= 0)
+ { pos(low); return(ans==0); }
+
+ /* initialize high to "line" after last line */
+ high= s_size;
+
+ mid= nextline(stream, nexttry );
+ while (mid < high )
+ { getline(stream,line);
+ if (fold) foldline(line);
+ if (strcmp(line,word) < 0) low= mid;
+ else high= mid;
+ mid= nextline(stream, nexttry );
+ }
+
+ /* linear search from low to high */
+ low= nextline(stream,low);
+ for(;;)
+ { if (low>=high) break;
+
+ getline(stream,line);
+ if (fold) foldline(line);
+ ans=strcmp(line,word);
+
+ if (ans>=0) break;
+ low= ftell(stream);
+ }
+
+ pos(low);
+ if (low==high) return(0);
+ else return(ans==0);
+}
+
+
+/* foldline(p): change all uppercase to lowercase in string p
+*/
+foldline(p)
+char *p;
+{ for (; *p!=NULL; p++)
+ { if (isupper(*p)) *p = tolower(*p);
+ }
+}
diff --git a/biblio/tib/src/streams.c b/biblio/tib/src/streams.c
new file mode 100644
index 0000000000..9fa362c355
--- /dev/null
+++ b/biblio/tib/src/streams.c
@@ -0,0 +1,136 @@
+#include "stdio.h"
+#include "ctype.h"
+#include "tib.h"
+#define pos(x) fseek(stream,x,0)
+
+long int nextrecord(), recsize(), nextline();
+
+/* getword(stream,p,ignore):
+ read next sequence of nonspaces on current line into *p.
+ null if no more words on current line.
+ %x (x in ignore) terminates line.
+ all words of the form %a are returned as null.
+ *p is a null terminated string (char p[MAXSTR]).
+*/
+getword(stream,p,ignore)
+FILE *stream;
+char *p, *ignore;
+{ char c;
+ char *oldp, *stop;
+
+ oldp= p;
+ stop= p+MAXSTR-1;
+ do{ c= getc(stream);
+ } while (isspace(c) && c!='\n');
+
+ while (!isspace(c))
+ { *p= c;
+ if (p < stop) p++;
+ c= getc(stream);
+ }
+ *p= NULL;
+
+ if (oldp[0]=='%')
+ { oldp[0]= NULL;
+ if (index(ignore, oldp[1]) != NULL)
+ while (c!='\n') c=getc(stream);
+ }
+}
+
+
+
+/* recsize(stream,start):
+ returns length of record beginning at start
+ (record ends at blank line or eof)
+ assumes and retains stream positioned at start
+*/
+long int recsize(stream,start)
+FILE *stream;
+long int start;
+{ char c; /* length = # of chars from start to beginning */
+ long int length; /* of current line. c in current line. */
+ int nonspaces; /* nonspaces = # of nonspaces in current line. */
+
+ nonspaces= 0;
+ c= getc(stream);
+ length= 0L;
+
+ while ( (c!='\n' || nonspaces!=0) && c!=EOF)
+ { if (c=='\n')
+ { length= ftell(stream)-start;
+ nonspaces= 0;
+ }
+ else if (!isspace(c)) nonspaces++;
+
+ c= getc(stream);
+ }
+
+ pos(start);
+ return(length);
+}
+
+
+/* nextrecord(stream,x): seeks in stream for first non-blank line
+ at or after char x in stream. seeks to eof if x is past last record.
+ x is the index of a character in the file (not eof).
+ returns position in stream. (returns EOF, if seeks to EOF)
+*/
+long int nextrecord(stream,x)
+FILE *stream;
+long int x;
+{ long int start; /* position of the beginning of the line */
+ char c; /* containing c */
+
+ pos(x);
+ start= x;
+ /* find start of first non-blank record */
+ for(;;)
+ { c= getc(stream);
+ if (c=='\n') start= ftell(stream);
+ else if (!isspace(c)) break;
+ }
+
+ if (feof(stream)) { pos(start); start= EOF; }
+ else pos(start);
+ return(start);
+}
+
+/* nextline(stream,x): seeks in stream after first newline at or after
+ char x in stream. seeks to eof if x is in last line.
+ x is the index of a character in the file (not eof).
+ returns position in stream
+*/
+long int nextline(stream,x)
+FILE *stream;
+long int x;
+{ char c;
+
+ pos(x);
+ do {
+ c = getc(stream);
+ } while ((c != '\n') && (c != EOF)) ;
+ return(ftell(stream));
+}
+
+/* printline(stream): copies stream up to a newline
+*/
+printline(stream)
+FILE *stream;
+{ char c;
+ while ((c=getc(stream)) != '\n' && c!=EOF) putchar(c);
+ putchar('\n');
+}
+
+/* getline(stream,p): store in *p next chars in stream up to \n
+ advance stream past \n.
+ limit of MAXSTR-1 chars may be stored at p.
+*/
+getline(stream,p)
+FILE *stream;
+char *p;
+{ char *stop;
+ stop= p+MAXSTR-1;
+ while ( (*p= getc(stream)) != '\n' && *p!=EOF)
+ if (p<stop) p++;
+ *p= NULL;
+}
diff --git a/biblio/tib/src/tib.c b/biblio/tib/src/tib.c
new file mode 100644
index 0000000000..fe448c10fe
--- /dev/null
+++ b/biblio/tib/src/tib.c
@@ -0,0 +1,775 @@
+/*
+ Tib - TeX bibliographic formatter
+
+ Written by J.C. Alexander, University of Maryland
+ based on "bib," a troff formatter,
+ written by Tim Budd, University of Arizona. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "tib.h"
+
+#define getch(c,fd) (c = getc(fd))
+#define echoc(c,ifd,ofd) (getch(c,ifd) == EOF ? c : putc(c,ofd))
+#define testc(c,d,ifd,ofd) (getch(c, ifd) == d ? putc(c, ofd) : 0)
+
+/* global variables */
+ FILE *rfd; /* reference temporary file */
+ char reffile[120]; /* temporary file (see tib.h) */
+ long int refspos[MAXREFS]; /* reference seek positions */
+ int unlmark[MAXREFS]; /* underline flags */
+ long int rend = 1; /* last position in rfd (first char unused)*/
+ int numrefs = -1; /* number of references generated so far */
+ FILE *tfd; /* output of pass 1 of file(s) */
+ char tmp_file[120]; /* output of pass 1 */
+ char common[] = COMFILE; /* common word file */
+ char *citestr[MAXREFS]; /* citation strings */
+ int findex = false; /* can we read the file INDEX ? */
+
+/* global variables in tibargs */
+ extern int foot, sort, personal, underline, silent, loccit, ibidflag[];
+ extern int hyphen, ordcite, biblineno, stndout, locflag[], optch2[], c0;
+ extern int inputflag;
+ extern char sortstr[], pfile[], citetemplate[], bibfname[], dirsp2[];
+ extern char suffix[];
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{ int rcomp1();
+ FILE *ofd; /* output file */
+ char *outname;
+ char *outfname(), *getenv(), *pcom, *pdefst, *ptemp;
+ int undrline();
+ char headerline[240];
+ char *indx = INDXFILE;
+ char *tfgets(), argchk[3];
+ int i, strcmp(), clnup();
+
+ /* header */
+ for (i = 1; i < argc; i++) {
+ strcpy(argchk,OPTCH);
+ strcat(argchk,"z");
+ if (strcmp(argv[i],argchk) == 0)
+ silent = true;
+ strcpy(argchk,OPTCH);
+ strcat(argchk,"|");
+ if (strcmp(argv[i],argchk) == 0)
+ silent = true;
+ }
+ if (silent == false)
+ fprintf (stderr, "Tib -- version %s, released %s.\n", VERSION, RDATE);
+
+ /* the file INDEX in the current directory is the default index,
+ if it is present */
+
+ rfd = fopen( INDXFILE , "r");
+ if (rfd != NULL) {
+ findex = true;
+ tfgets(headerline,240,rfd);
+ fclose(rfd);
+ chkindex(indx, headerline, false);
+ }
+
+ /* get file names from environment */
+
+ pcom = getenv("COMFILE");
+ if (pcom != NULL)
+ strcpy(common,pcom);
+ ptemp = getenv("TMPDIR");
+ if (ptemp != NULL) {
+ strcpy(reffile,ptemp);
+ strcat(reffile,dirsp2);
+ strcat(reffile,"tibrXXXXXX");
+ strcpy(tmp_file,ptemp);
+ strcat(tmp_file,dirsp2);
+ strcat(tmp_file,"tibpXXXXXX");
+ }
+ else {
+ strcat(reffile,TMPREFFILE);
+ strcat(tmp_file,TMPTEXTFILE);
+ }
+
+ /* open temporaries, reffile will contain references collected in
+ pass 1, and tmp_file will contain text. */
+
+ mktemp(reffile);
+ rfd = fopen(reffile,"w+");
+ if (rfd == NULL)
+ error("can't open temporary reference file");
+ putc('x', rfd); /* put garbage in first position (not used) */
+ mktemp(tmp_file);
+ tfd = fopen(tmp_file,"w");
+ if (tfd == NULL)
+ error("can't open temporary output file");
+
+ /*
+ pass1 - read files, looking for citations
+ arguments are read by doargs (tibargs.c)
+ */
+
+ pdefst = getenv("DEFSTYLE");
+ if (pdefst == NULL) {
+ if (doargs(argc, argv, DEFSTYLE ) == 0) {
+ strcpy(bibfname, "<stdin>");
+ rdtext(stdin);
+ }
+ }
+ else {
+ if (doargs(argc, argv, pdefst ) == 0) {
+ strcpy(bibfname, "<stdin>");
+ rdtext(stdin);
+ }
+ }
+
+ /*
+ sort references, make citations, add disambiguating characters
+ */
+
+ if (silent == 0)
+ fprintf(stderr, "Processing citations ...\n");
+ if (sort)
+ qsort(refspos, numrefs+1, sizeof(long), rcomp1);
+ makecites(citestr);
+ if (underline)
+ undrline();
+ if (citetemplate[0] != '0')
+ disambiguate();
+
+ /*
+ reopen temporaries
+ */
+
+ fclose(tfd);
+ tfd = fopen(tmp_file,"r");
+ if (tfd == NULL)
+ error("can't open temporary output file for reading");
+
+ /*
+ pass 2 - reread files, replacing references
+ */
+
+ if (stndout == true && bibfname != "<stdin>")
+ pass2(tfd, stdout);
+ else {
+ outname = outfname (bibfname);
+ ofd = fopen (outname, "w");
+ if (ofd == NULL) {
+ fprintf(stderr,"can't open %s\n", outname);
+ clnup();
+ exit(1);
+ }
+ else {
+ if (silent == 0)
+ fprintf(stderr, "Writing output file ...\n");
+ pass2 (tfd, ofd);
+ fprintf(ofd,"\n");
+ fclose (ofd);
+ fprintf (stderr,"Output of tib in %s.\n", outname);
+ }
+
+ }
+ fclose(tfd);
+ fclose(rfd);
+ clnup();
+ exit(0);
+}
+
+ /* clean up */
+ clnup()
+{
+ unlink(tmp_file);
+ unlink(reffile);
+ return;
+}
+/* getwd - get the next 'word' (terminated by non-alpha) from a file */
+char *
+ getwd(fd,getwdflag)
+ FILE *fd;
+ int getwdflag;
+ /* The next word is terminated by non-alpha if getwdflag = 0,
+ by whitespace if getwdflag != 0 */
+ /* The result is returned in str. */
+{ char c;
+ char str[120], *pstr;
+ int bracketflag; /* 1 if file name is enclosed in brackets */
+
+ bracketflag = 0;
+ pstr = str;
+ *pstr = NULL;
+
+ getch(c,fd);
+ if (getwdflag == 0) {
+ while (isalpha(c) != 0) {
+ *pstr++ = c;
+ getch(c,fd);
+ }
+ }
+ else {
+ while (c == ' '
+ || c == '\n'
+ || c == '\t'
+ || c == '\%'
+ || c == '{'
+ || c == EOF) {
+ if (c == EOF)
+ error("end of file after \\input");
+ if (c == '{') bracketflag = 1;
+ if (c == '\n') biblineno++;
+ if (c == '\%') {
+ while (c != '\n') getch(c,fd);
+ ungetc(c,fd);
+ }
+ getch(c,fd);
+ }
+ if (bracketflag == 0) {
+ while (c != ' '
+ && c != '\n'
+ && c != '\t'
+ && c != EOF) {
+ *pstr++ = c;
+ getch(c,fd);
+ }
+ }
+ else {
+ while (c != '}') {
+ if (c == EOF
+ || c == '\n'
+ || c == '\%') error("no right brackets on \\input file name");
+ *pstr++ = c;
+ getch(c,fd);
+ while (c == ' ' || c == '\t') getch(c,fd);
+ }
+ }
+ }
+ *pstr = NULL;
+ if (bracketflag == 0)
+ ungetc(c,fd); /* put the first char after wd back */
+ return(str);
+}
+
+/* rdtext - read and process a text file, looking for [. commands */
+ rdtext(fd)
+ FILE *fd;
+{ char lastc, c, d;
+ char cmd[120], *getwd();
+ char lastlc;
+ int sortdefs();
+ int percentflag; /* is there % so far on line? */
+ int putback;
+ int fctr = 0; /* count of input/include files in stack */
+ FILE *fstack[32]; /* stack of input/include files */
+ char fnm[32][120]; /* stack of input/include files names */
+ char bibfnamet[120]; /* temporary file name */
+ int biblinenostack[32]; /* stack of line numbers */
+
+ sortdefs();
+ lastc = '\0';
+ lastlc = '\0';
+ percentflag = false;
+ biblineno = 1;
+ fprintf(tfd,"%cmessage {DOCUMENT TEXT}\n",'\\');
+ while (getch(c, fd) != EOF || fctr != 0) {
+ if (c == EOF && fctr != 0) { /* pop file from stack */
+ fprintf(tfd,"%c",lastc);
+ fclose(fd);
+ strcpy(bibfnamet, bibfname);
+ strcpy(bibfname, fnm[--fctr]);
+ biblineno = biblinenostack[fctr];
+ fd = fstack[fctr];
+ fprintf(stderr, "... processing of %s complete, returning to %s ...\n", bibfnamet, bibfname);
+ fprintf(tfd,"\\message{)}%%");
+ c = NULL;
+ }
+
+ if (c == '\\' && percentflag == false && inputflag == true) {
+ if (lastc != NULL) putc(lastc,tfd);
+ strcpy(cmd,getwd(fd,0));
+ if (strcmp(cmd,"input")==0) {
+ /* found an input file */
+ strcpy(fnm[fctr], bibfname); /* push current file */
+ biblinenostack[fctr] = biblineno;
+ biblineno = 1;
+ if (fctr == 32)
+ error("\\input files nested too deeply");
+ fstack[fctr++] = fd;
+ strcpy(bibfname,getwd(fd,1)); /* get new file name */
+ putback = false;
+ fd = fopen(bibfname,"r");
+ if (fd == NULL) { /* file not found; */
+ strcpy(bibfnamet,bibfname); /* try adding .tex */
+ strcat(bibfname,suffix);
+ fd = fopen(bibfname,"r");
+ if (fd == NULL) { /* still can't be found; */
+ strcpy(bibfname, fnm[--fctr]); /* pop file */
+ fd = fstack[fctr];
+ biblineno = biblinenostack[fctr];
+ if (stndout == false && silent == false)
+ fprintf (stderr, "'%s', line %d: unable to locate %s, assuming it has no references\n", bibfname, biblineno, bibfnamet);
+ putback = true;
+ }
+ }
+ if (putback == false) {
+ if (stndout == false && silent == false)
+ fprintf(stderr, "Reading input document file %s and looking up references ...\n", bibfname);
+ fprintf(tfd,"\\message{(%s input by Tib}%%\n", bibfname);
+ }
+ else {
+ fprintf(tfd,"%c",'\\'); /* pass chars on to */
+ fprintf(tfd,"%s",cmd); /* output file */
+ fprintf(tfd,"%c",' ');
+ fprintf(tfd,"%s",bibfnamet);
+ putback = false;
+ }
+ }
+ else { /* this is just text; */
+ fprintf(tfd,"%c",'\\'); /* pass it to the file */
+ fprintf(tfd,"%s",cmd);
+ }
+ c = NULL;
+ lastc = NULL;
+ }
+
+ if (c == '\%')
+ if (percentflag == false)
+ if (lastc != '\\') {
+ percentflag = true;
+ if (isalpha(lastc) == 0)
+ if (lastc != '\n')
+ if (lastc != '\0')
+ if (lastc != ']')
+ if (lastc != '>') {
+ lastlc = lastc;
+ lastc = '\0';
+ }
+ }
+ if ((c == '[' || c == '<') && lastc != '\\')
+ if (getch(d, fd) == '.') { /* found a reference */
+ if (c == '<') { if (lastc) fprintf(tfd,"%c",lastc);}
+ else
+ switch (lastc) {
+ case '\0':
+ case ' ': fprintf(tfd,"%cLspace ",'\\'); break;
+ case '.': fprintf(tfd,"%cLperiod ",'\\'); break;
+ case ',': fprintf(tfd,"%cLcomma ",'\\'); break;
+ case '?': fprintf(tfd,"%cLquest ",'\\'); break;
+ case ':': fprintf(tfd,"%cLcolon ",'\\'); break;
+ case ';': fprintf(tfd,"%cLscolon ",'\\'); break;
+ case '!': fprintf(tfd,"%cLbang ",'\\'); break;
+ case '\'': fprintf(tfd,"%cLquote ",'\\'); break;
+ case '"': fprintf(tfd,"%cLqquote ",'\\'); break;
+ case '`': fprintf(tfd,"%cLrquote ",'\\'); break;
+ default: fprintf(tfd,"%c",lastc); break;
+ }
+ rdcite(fd, c);
+ if (c == '[')
+ switch (lastc) {
+ case '\0': break;
+ case ' ': fprintf(tfd,"%cRspace{}",'\\'); break;
+ case '\n': fprintf(tfd,"%cRspace{}",'\\'); break;
+ case '.': fprintf(tfd,"%cRperiod{}",'\\'); break;
+ case ',': fprintf(tfd,"%cRcomma{}",'\\'); break;
+ case '?': fprintf(tfd,"%cRquest{}",'\\'); break;
+ case ':': fprintf(tfd,"%cRcolon{}",'\\'); break;
+ case ';': fprintf(tfd,"%cRscolon{}",'\\'); break;
+ case '!': fprintf(tfd,"%cRbang{}",'\\'); break;
+ case '\'': fprintf(tfd,"%cRquote{}",'\\'); break;
+ case '"': fprintf(tfd,"%cRqquote{}",'\\'); break;
+ case '`': fprintf(tfd,"%cRrquote{}",'\\'); break;
+ }
+ lastc = '\0';
+ }
+ else {
+ if (lastc != '\0') putc(lastc, tfd);
+ ungetc(d, fd);
+ lastc = c;
+ }
+ else {
+ if (lastc != '\0') putc(lastc, tfd);
+ lastc = c;
+ if (c == '\n' || c == EOF) {
+ biblineno++;
+ percentflag = false;
+ if (lastlc != '\0') {
+ putc(c,tfd);
+ getch(d, fd);
+ if (d == ' ' || d == '\n' || d == '\t' || d == '\%'
+ || d == '.') {
+ ungetc(d, fd);
+ putc(lastlc,tfd);
+ lastlc = '\0';
+ putc('\%',tfd);
+/* putc('\n',tfd); */
+ }
+ else {
+ ungetc(d, fd);
+ lastc = lastlc;
+ lastlc = '\0';
+ }
+ }
+ }
+ }
+ }
+ if (lastc != '\0') putc(lastc, tfd);
+}
+
+/* rdcite - read citation information inside a [. command */
+ rdcite(fd, ch)
+ FILE *fd;
+ char ch;
+{ long int n, getref();
+ char huntstr[HUNTSIZE], c, info[HUNTSIZE], footch[2], c0ch[2];
+
+ if (foot)
+ strcpy(footch,"\n");
+ else
+ strcpy(footch,"");
+ if (c0)
+ strcpy(c0ch,"\n");
+ else
+ strcpy(c0ch,"");
+ if (ch == '[')
+ fprintf(tfd,"%cLcitemark ", '\\');
+ else
+ fprintf(tfd,"%cLAcitemark ", '\\');
+ huntstr[0] = info[0] = 0;
+ while (getch(c, fd) != EOF)
+ switch (c) {
+ case ',':
+ n = getref(huntstr);
+ if (n > 0)
+ fprintf(tfd, "%c%ld%c%s%c", CITEMARK, n, CITEMARK, info,
+ CITEEND);
+ else
+ fprintf(tfd, "%c0%c%s%s%c", CITEMARK, CITEMARK,
+ huntstr, info, CITEEND);
+ huntstr[0] = info[0] = 0;
+ break;
+
+ case '.':
+ while (getch(c, fd) == '.') ;
+ if (c == ']') {
+ n = getref(huntstr);
+ if (n > 0) {
+ fprintf(tfd, "%c%ld%c%s%c%s%cRcitemark %s", CITEMARK, n,
+ CITEMARK, info, CITEEND, c0ch,'\\',footch);
+/* if (foot) {
+ getch(c, fd);
+ if (c == ' '|| c== '\n')
+ fprintf(tfd, "%c ", '\\');
+ else
+ putc(c, tfd);
+ fprintf(tfd, "\n");
+ }*/
+ }
+ else {
+ fprintf(tfd, "%c0%c%s%s%c%s%cRcitemark%s ", CITEMARK, CITEMARK,
+ huntstr, info, CITEEND,c0ch, '\\',footch);
+/* if (foot) {
+ getch(c, fd);
+ if (c == ' '|| c== '\n')
+ fprintf(tfd, "%c ", '\\');
+ else
+ putc(c, tfd);
+ fprintf(tfd, "\n");
+ }*/
+ }
+ return;
+ }
+ else if (c == '>') {
+ n = getref(huntstr);
+ if (n > 0) {
+ fprintf(tfd, "%c%ld%c%s%c%s%cRAcitemark{}%s", CITEMARK, n,
+ CITEMARK, info, CITEEND,c0ch,'\\',footch);
+ }
+ else {
+ fprintf(tfd, "%c0%c%s%s%c%s%cRAcitemark{}%s", CITEMARK,
+ CITEMARK,huntstr, info, CITEEND,c0ch,'\\',footch);
+ }
+ return;
+ }
+ else
+ addc(huntstr, c);
+ break;
+
+ case '<':
+ strcat(info, "\\LIcitemark{}");
+ while (getch(c, fd) != '>')
+ if (c == EOF) {
+ fprintf(stderr, "Error: ill formed reference\n");
+ clnup();
+ exit(1);
+ }
+ else
+ addc(info, c);
+ strcat(info, "\\RIcitemark ");
+ break;
+
+ case '\n':
+ biblineno++;
+ case '\t':
+ c = ' '; /* fall through */
+
+ default:
+ addc(huntstr,c);
+ }
+ error("end of file reading citation");
+}
+
+/* addc - add a character to hunt string */
+ addc(huntstr, c)
+ char huntstr[HUNTSIZE], c;
+{ int i;
+
+ i = strlen(huntstr);
+ if (i > HUNTSIZE)
+ error("citation too long");
+ huntstr[i] = c;
+ huntstr[i+1] = 0;
+}
+
+/* getref - if an item was already referenced, return its pointer in
+ the reference file, otherwise create a new entry */
+ long int getref(huntstr)
+ char huntstr[HUNTSIZE];
+{ char rf[REFSIZE], ref[REFSIZE], *r, *hunt();
+ int i, match(), getwrd();
+
+ r = hunt(huntstr);
+ if (r != NULL) {
+ /* expand defined string */
+ strcpy(rf, r);
+ free(r);
+ expnd2(rf);
+
+ /* see if reference has already been cited */
+
+ if (foot == false)
+ for (i = 0; i <= numrefs; i++) {
+ rdref(refspos[i], ref);
+ if (strcmp(ref, rf) == 0)
+ return(refspos[i]);
+ }
+
+ if (loccit) {
+ ibidflag[numrefs+1] = false;
+ locflag[numrefs+1] = false;
+ for (i = 0; i <= numrefs; i++) {
+ rdref(refspos[i], ref);
+ if (strcmp(ref, rf) == 0) {
+ locflag[numrefs+1] = true;
+ break;
+ }
+ }
+ rdref(refspos[numrefs], ref);
+ if (strcmp(ref, rf) == 0)
+ ibidflag[numrefs+1] = true;
+ }
+
+ /* didn't match any existing reference, create new one */
+
+ numrefs++;
+ refspos[numrefs] = rend;
+#ifdef READWRITE
+ fixrfd( WRITE ); /* fix access mode of rfd, if nec. */
+#else
+ fseek(rfd, rend, 0); /* go to end of rfd */
+#endif
+ i = strlen(rf) + 1;
+ fwrite(rf, 1, i, rfd);
+ rend = rend + i;
+ return(refspos[numrefs]);
+ }
+ else {
+ bibwarning("no reference matching %s\n", huntstr);
+ return( (long) -1 );
+ }
+}
+
+/* hunt - hunt for reference from either personal or system index */
+ char *hunt(huntstr)
+ char huntstr[];
+{ char *fhunt(), *r, *p, *q, fname[120];
+ char *getenv(), *pindx;
+
+ if (personal) {
+ for (p = fname, q = pfile; ; q++)
+ if (*q == ',' || *q == 0) {
+ *p = 0;
+ if ((r = fhunt(fname, huntstr)) != NULL)
+ return(r);
+ else if (*q == 0)
+ break;
+ p = fname;
+ }
+ else *p++ = *q;
+ }
+ else if (findex) {
+ if ((r = fhunt( INDXFILE , huntstr)) != NULL)
+ return(r);
+ }
+ pindx = getenv("SYSINDEX");
+ if (pindx == NULL) {
+ if ((r = fhunt(SYSINDEX , huntstr)) != NULL)
+ return(r);
+ }
+ else {
+ if ((r = fhunt(pindx , huntstr)) != NULL)
+ return(r);
+ }
+ return(NULL);
+}
+
+/* fhunt - hunt from a specific file */
+ char *fhunt(file, huntstr)
+ char file[], huntstr[];
+{ char *p, *r, *locate();
+
+ r = locate(huntstr, file, 6, common);
+
+ if (r == NULL)
+ return(NULL); /* error */
+ if (*r == 0)
+ return(NULL); /* no match */
+
+ for (p = r; *p; p++)
+ if (*p == '\n')
+ if (*(p+1) == '\n') { /* end */
+ if (*(p+2) != 0)
+ bibwarning("multiple references match %s\n",huntstr);
+ *(p+1) = 0;
+ break;
+ }
+ else if (*(p+1) != '%' && *(p+1) != '.') /* unnecessary newline */
+ *p = ' ';
+ return(r);
+}
+
+/* putrefs - gather contiguous references together, sort them if called
+ for, hyphenate if necessary, and dump them out */
+int putrefs(ifd, ofd, footrefs, fn)
+FILE *ifd, *ofd;
+int fn, footrefs[];
+{ int citenums[MAXATONCE]; /* reference numbers */
+ char *citeinfo[MAXATONCE]; /* reference information */
+ char infoword[HUNTSIZE]; /* information line */
+ int rtop, n, i, j; /* number of citations being dumped */
+ char c, *p, *walloc();
+
+/* first gather contiguous references together, and order them if
+ required */
+
+ rtop = -1;
+ do {
+ n = 0;
+ while (isdigit(getch(c, ifd)))
+ n = 10 * n + (c - '0');
+ if (c ^= CITEMARK)
+ error("inconsistant citation found in pass two");
+ if (n == 0) { /* reference not found */
+ rtop++;
+ j = rtop;
+ citenums[j] = -1;
+ citeinfo[j] = 0;
+ }
+ else {
+ for (i = 0; i <= numrefs; i++)
+ if (refspos[i] == n) { /* its the ith item in reference list */
+ rtop++;
+ j = rtop;
+ if (ordcite)
+ for ( ; j > 0 && citenums[j-1] > i; j--) {
+ citenums[j] = citenums[j-1];
+ citeinfo[j] = citeinfo[j-1];
+ }
+ citenums[j] = i;
+ citeinfo[j] = 0;
+ break;
+ }
+ if (i > numrefs)
+ error("citation not found in pass two");
+ }
+ if (getch(c, ifd) != CITEEND) {
+ for (p = infoword; c != CITEEND ; ) {
+ *p++ = c;
+ getch(c, ifd);
+ }
+ *p = 0;
+ citeinfo[j] = walloc(infoword);
+ }
+ getch(c, ifd);
+ } while (c == CITEMARK);
+ ungetc(c, ifd);
+
+ /* now dump out values */
+ for (i = 0; i <= rtop; i++) {
+ if (citenums[i] >= 0)
+ fputs(citestr[citenums[i]], ofd);
+ if (citeinfo[i]) {
+ fputs(citeinfo[i], ofd);
+ free(citeinfo[i]);
+ }
+ if (hyphen) {
+ for (j = 1; j + i <= rtop && citenums[i+j] == citenums[i] + j; j++);
+ if (j + i > rtop) j = rtop;
+ else j = j + i - 1;
+ }
+ else
+ j = i;
+ if (j > i + 1) {
+ fputs("\\Citehyphen ", ofd);
+ i = j - 1;
+ }
+ else if (i != rtop)
+ if (!c0) fputs("\\Citecomma\n", ofd);
+ if ((foot) || (c0)) {
+ fn++;
+ footrefs[fn] = citenums[i];
+ }
+ }
+ return(fn);
+}
+
+/* pass2 - read pass 1 files entering citation */
+ pass2(ifd, ofd)
+ FILE *ifd, *ofd;
+{
+ char c, d, e;
+ int i, fn, footrefs[25], dumped;
+
+ fn = -1;
+ if ((foot) || (c0)) dumped = true;
+ else dumped = false;
+ while (getch(c, ifd) != EOF) {
+ while (c == '\n') {
+ putc(c, ofd);
+ if (((foot) || (c0)) && fn >= 0) {
+ for (i = 0; i <= fn; i++)
+ dumpref(footrefs[i], ofd);
+ fn = -1;
+ }
+ if (getch(c,ifd) != '.')
+ ;
+ else if (getch(d,ifd) != '[')
+ ungetc(d,ifd);
+ else if (getch(e,ifd) != ']') {
+ ungetc(e,ifd);
+ ungetc(d,ifd);}
+ else if ((foot == false) && (c0 == false)) {
+ while (echoc(c, ifd, ofd) != '\n')
+ ;
+ dumped = true;
+ fprintf(ofd,"\\message{REFERENCE LIST}\n\n");
+ for (i = 0; i <= numrefs; i++)
+ dumpref(i, ofd);
+ getch(c, ifd);
+ }
+ }
+ if (c == CITEMARK)
+ fn = putrefs(ifd, ofd, footrefs, fn);
+ else if (c != EOF)
+ putc(c, ofd);
+ }
+ if (dumped == false)
+ bibwarning("Warning: reference list not made -- .[] not encountered\n","");
+}
diff --git a/biblio/tib/src/tibargs.c b/biblio/tib/src/tibargs.c
new file mode 100644
index 0000000000..2d367df10e
--- /dev/null
+++ b/biblio/tib/src/tibargs.c
@@ -0,0 +1,1876 @@
+/*
+ tibargs
+
+ read argument strings for tib and tiblist
+ do name formatting, printing lines, other actions common to both
+
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "tib.h"
+
+/* global variables */
+ char bibfname[120]; /* file name currently being read */
+ int biblineno; /* line number currently being referenced */
+ int abbrev = false; /* automatically abbreviate names */
+ int capsmcap = false; /* print names in caps small caps (CACM form)*/
+ int numrev = 0; /* number of authors names to reverse */
+ int edabbrev = false; /* abbreviate editors names ? */
+ int edcapsmcap = false; /* print editors in cap small caps */
+ int ednumrev = 0; /* number of editors to reverse */
+ int sort = false; /* sort references ? (default no) */
+ int foot = false; /* footnoted references ? (default endnotes) */
+ int c0 = false; /* references in text ? (default no) */
+ int hyphen = false; /* hypenate contiguous references */
+ int ordcite = true; /* order multiple citations */
+ int specflag = false; /* use special flags */
+ int loccit = false; /* use ibid and loccit in footnotes */
+ int onepage = false; /* print only first page of reference */
+ int underline = false; /* underline multiple references */
+ int silent = false; /* run silently */
+ int stndout = false; /* output on stdout */
+ int inputflag = false; /* process input/include files */
+ char sortstr[80] = "1"; /* sorting template */
+ char trailstr[80] = ""; /* trailing characters to output */
+ char pfile[120]; /* private file name */
+ char dirname[120] =""; /* private directory name */
+ int personal = false; /* personal file given ? (default no) */
+ char citetemplate[80] = "1"; /* citation template */
+ char *words[MAXDEFS]; /* defined words */
+ char *defs[MAXDEFS]; /* defined word definitions */
+ long int defpos[MAXDEFS]; /* position of defined words */
+ long int link[MAXDEFS]; /* link for linking defined words on input */
+ long int jtop = 0; /* entry for linked list */
+ long int wordtop = -1; /* top of defined words array */
+ int locflag[MAXREFS]; /* loc cit ? */
+ int ibidflag[MAXREFS]; /* ibid ? */
+ char dirsp2[]=DIRSEP; /* directory separator character */
+ char optch2[]=OPTCH; /* option character on program calls */
+ char suffix[5] = ".tex"; /* for appending to file names */
+ int startflag = 1; /* starting count of Flags */
+
+/* where output goes */
+ extern FILE *tfd;
+/* reference file information */
+ extern long int refspos[];
+ extern int unlmark[];
+ extern char reffile[];
+ extern FILE *rfd;
+ extern char *citestr[];
+ extern int numrefs;
+
+/* doargs - read command argument line for both tib and tiblist
+ set switch values
+ call rdtext on file arguments, after dumping
+ default style file if no alternative style is given
+*/
+ int doargs(argc, argv, defstyle)
+ int argc;
+ char **argv, defstyle[];
+{ int numfiles, i, style;
+ char bibfnamet[120];
+ int pipeflag = false;
+ int fileflag = false;
+ char *p, *q, *walloc();
+ FILE *fd, *np;
+ char headerline[240], fname[240];
+ char *tfgets(), *ptmac, *getenv();
+
+ if (silent == false)
+ fprintf(stderr, "Processing format commands ...\n");
+ numfiles = 0;
+ style = true;
+ ptmac = getenv("TMACLIB");
+ if (ptmac == NULL)
+ ptmac = TMACLIB;
+ words[0] = walloc("TMACLIB");
+ strcpy(headerline,ptmac);
+ strcat(headerline,dirsp2);
+ defs[0] = walloc(headerline);
+ wordtop++;
+ link[0] = -1;
+ fprintf(tfd, "%cmessage {REFERENCE FORMATTING FILES:}\n", '\\');
+ fprintf(tfd, "%cdef%cTMACLIB{%s%c}\n", '\\', '\\', ptmac, dirsp2[0]);
+ fprintf(tfd, "%cinput %cTMACLIB Macros.ttx\n", '\\', '\\');
+
+ for (i = 1; i < argc; i++)
+ if (argv[i][0] == optch2[0] && argv[i][1] == 'd') {
+ if (argv[i][2])
+ p = &argv[i][2];
+ else { /* take next arg */
+ i++;
+ if (i == argc) {
+ fprintf(stderr,"command line: illegal switch %s\n", argv[i-1]);
+ clnup();
+ exit(1);
+ }
+ p = argv[i];
+ }
+ strcpy(dirname,p);
+ break;
+ }
+
+ for (i = 1; i < argc; i++)
+ if (argv[i][0] == optch2[0]) {
+ switch(argv[i][1]) {
+
+ case 'd': if (argv[i][2])
+ p = &argv[i][2];
+ else { /* take next arg */
+ i++;
+ if (i == argc) {
+ fprintf(stderr,
+ "command line: illegal switch %s\n", argv[i-1]);
+ clnup();
+ exit(1);
+ }
+ p = argv[i];
+ }
+ strcpy(dirname,p);
+ break;
+
+ case 'j': inputflag = true;
+ break;
+
+ case 'n': if (argv[i][2])
+ startflag = atoi(&argv[i][2]);
+ else { /* take next arg */
+ i++;
+ if (i == argc) {
+ fprintf(stderr,
+ "command line: illegal switch %s\n", argv[i-1]);
+ clnup();
+ exit(1);
+ }
+ startflag = atoi(argv[i]);
+ }
+ break;
+
+ case 'p': if (argv[i][2])
+ p = &argv[i][2];
+ else { /* take next arg */
+ i++;
+ if (i == argc) {
+ fprintf(stderr,
+ "command line: illegal switch %s\n", argv[i-1]);
+ clnup();
+ exit(1);
+ }
+ p = argv[i];
+ }
+ strcpy(pfile, p);
+ personal = true;
+ for (p = fname, q = pfile; ; q++)
+ if (*q == ',' || *q == 0) {
+ *p = 0;
+ np = fopen( fname, "r");
+ if (np == NULL) {
+ fprintf(stderr, "Can't open index %s\n",fname);
+ clnup();
+ exit(1);
+ }
+ else {
+ tfgets(headerline,240,np);
+ fclose(np);
+ chkindex(fname, headerline, true);
+ }
+ if (*q == 0)
+ break;
+ p = fname;
+ }
+ else *p++ = *q;
+ break;
+
+ case 's': style = false; /*fall through*/
+ case 'i': if (argv[i][2])
+ p = &argv[i][2];
+ else { /* take next arg */
+ i++;
+ if (i == argc) {
+ fprintf(stderr,
+ "command line: illegal switch %s\n", argv[i-1]);
+ clnup();
+ exit(1);
+ }
+ p = argv[i];
+ }
+ incfile(p);
+ break;
+
+ case 'x': stndout = true;
+ break;
+
+ case 'z': silent = true;
+ break;
+
+ case '|': pipeflag = true;
+ stndout = true;
+ break;
+
+ default: fprintf(stderr, "command line: invalid switch %s\n",
+ argv[i]);
+ clnup();
+ exit(1);
+ }
+ }
+ else { /* file name */
+ numfiles++;
+ fileflag = true;
+ if (style) {
+ style = false;
+ incfile( defstyle );
+ }
+ strcpy(bibfname, argv[i]);
+ fd = fopen(argv[i], "r");
+ if (fd == NULL) {
+ strcat(bibfname,suffix);
+ fd=fopen(bibfname, "r");
+ if (fd == NULL) {
+ fprintf(stderr, "can't open %s or %s\n", argv[i], bibfname);
+ clnup();
+ exit(1);
+ }
+ }
+ if (stndout == false && silent == false) {
+ fprintf(stderr, "Reading input document file %s and looking up references ...\n", bibfname);
+ }
+ rdtext(fd);
+ fclose(fd);
+ }
+ if (style) incfile( defstyle );
+ if (fileflag == false) /* no input file on command line */
+ if (pipeflag == true) {
+ strcpy(bibfname, "<stdin>");
+ rdtext(stdin);
+ numfiles++;
+ }
+ else {
+ fprintf(stderr, "Enter input file: ");
+ scanf("%s", bibfnamet);
+ numfiles++;
+ strcpy(bibfname, bibfnamet);
+ fd = fopen(bibfnamet, "r");
+ if (fd == NULL) {
+ strcat(bibfname, ".tex");
+ fd=fopen(bibfname, "r");
+ if (fd == NULL) {
+ fprintf(stderr, "can't open %s or %s\n",
+ bibfnamet, bibfname);
+ clnup();
+ exit(1);
+ }
+ }
+ if (stndout == false && silent == false) {
+ fprintf(stderr, "Reading input document file %s and looking up references ...\n", bibfname);
+ }
+ rdtext(fd);
+ fclose(fd);
+ }
+ return(numfiles);
+}
+
+/* chkindex - check if index is up to date */
+ int chkindex(indx, header, pflag)
+ char *indx;
+ char header[240];
+ int pflag;
+{ char *c, *q, *p;
+ char indx0[240], indx00[80], *indx1, indx11[240];
+ char *rindex();
+ struct stat buf;
+ FILE *np;
+ int i, j, qflag;
+ time_t timefile, timeindx;
+
+ stat(indx, &buf);
+ timeindx = buf.st_mtime;
+ strcpy (indx0,indx);
+ c = rindex(indx0, dirsp2[0]);
+ if (c == NULL)
+ indx00[0] = '\0';
+ else {
+ *++c = '\0';
+ strcpy (indx00, indx0);
+ }
+ strcpy (indx0,indx00);
+ qflag = true;
+ for (q = header ; *q;) {
+ for (;*q == ' ';q++);
+ if (*q == '\0') break;
+ for (indx1 = q; *q && *q != ' '; q++);
+ if (*q)
+ *q = '\0';
+ else
+ qflag = false;
+ if (*indx1 != dirsp2[0]) {
+ strcat (indx0,indx1);
+ strcpy (indx11,indx0);
+ }
+ np = fopen(indx11,"r");
+ if (np == NULL) {
+ fprintf(stderr,"Cannot locate reference file %s\n", indx11);
+ clnup();
+ exit(1);
+ }
+ strcpy (indx0, indx00);
+ stat(indx11, &buf);
+ timefile = buf.st_mtime;
+ if (qflag == true)
+ *q = ' ';
+ if (timeindx < timefile) {
+ fprintf(stderr,"Index %s not up to date\n", indx);
+ if (pflag)
+ fprintf(stderr,"Use tibdex (in appropriate directory) with reference file(s)%s\n",header);
+ else
+ fprintf(stderr," Use: tibdex%s\n",header);
+ clnup();
+ exit(1);
+ }
+ }
+ }
+
+/* outfname - make output file name */
+ char *outfname(mp)
+ char *mp;
+{ char *q;
+
+ for (q=mp; *q; q++);
+ if (*--q == 'x')
+ if (*--q == 'e')
+ if (*--q == 't')
+ if (*--q == '.')
+ *q='\0';
+ strcat (mp, "-t.tex");
+ return (mp);
+}
+
+/* incfile - read in an included file */
+incfile(np)
+ char *np;
+{ char name[120];
+ FILE *fd;
+ char *p, line[LINELENGTH], dline[LINELENGTH], word[80], *tfgets();
+ int i, j, k, getwrd();
+ int located, j1;
+ char *ptmac, *getenv();
+
+ ptmac = getenv("TMACLIB");
+ if (ptmac == NULL)
+ ptmac = TMACLIB;
+ strcpy(bibfname, np);
+ fd = fopen(np, "r");
+ if (fd == NULL && *np != dirsp2[0]) {
+ strcpy(name, np);
+ strcat(name, ".tib");
+ strcpy(bibfname, name);
+ fd = fopen(name, "r");
+ }
+ if (fd == NULL && *np != dirsp2[0])
+ if (dirname[0] != '\0') {
+ strcpy(name, dirname);
+ strcat(name, dirsp2);
+ strcat(name, np);
+ strcpy(bibfname, name);
+ fd = fopen(name, "r");
+ }
+ if (fd == NULL && *np != dirsp2[0])
+ if (dirname[0] != '\0') {
+ strcpy(name, dirname);
+ strcat(name, dirsp2);
+ strcat(name, np);
+ strcat(name, ".tib");
+ strcpy(bibfname, name);
+ fd = fopen(name, "r");
+ }
+ if (fd == NULL && *np != dirsp2[0]) {
+ strcpy(name, ptmac);
+ strcat(name, dirsp2);
+ strcat(name, np);
+ strcpy(bibfname, name);
+ fd = fopen(name, "r");
+ }
+ if (fd == NULL && *np != dirsp2[0]) {
+ strcpy(name, ptmac);
+ strcat(name, dirsp2);
+ strcat(name, np);
+ strcat(name, ".tib");
+ strcpy(bibfname, name);
+ fd = fopen(name, "r");
+ }
+ if (fd == NULL) {
+ bibwarning("%s: can't open\n", np);
+ clnup();
+ exit(1);
+ }
+
+ /* now go off and process file */
+ fprintf(tfd, "%cmessage {(%s}\n", '\\', np);
+ biblineno = 1;
+ while (tfgets(line, LINELENGTH, fd) != NULL) {
+ biblineno++;
+ switch(line[0]) {
+
+ case '#': break;
+
+ case 'A': for (p = &line[1]; *p && *p != ' '; p++) {
+ if (*p == 'A')
+ abbrev = true;
+ else if (*p == 'X')
+ capsmcap = true;
+ else if (*p == 'R') {
+ if (isdigit(*(p+1)))
+ numrev = atoi(p+1);
+ else
+ numrev = 1000;
+ }
+ }
+ break;
+
+ case 'C': for (p = &line[1]; *p == ' '; p++) ;
+ strcpy(citetemplate, p);
+ for (p=citetemplate; *p && *p != ' '; p++);
+ *p=0;
+ if (citetemplate[0] == '0') c0 = true;
+ break;
+
+ case 'D': if ((k = getwrd(line, 1, word)) == 0)
+ error("word expected in definition");
+
+/* this creates a linked list for use in sortdefs and expnd2
+ but it is fortran style, not good c style -- fix later */
+
+ j=jtop;
+ for (located = false; located == false; ) {
+ i=strcmp(word, words[jtop]);
+ if (i == 0) {
+ located = true;
+ break;
+ }
+ if (i > 0) {
+ wordtop++;
+ if (wordtop > MAXDEFS)
+ error("too many definitions:");
+ link[wordtop] = jtop;
+ jtop = wordtop;
+ j = jtop;
+ words[wordtop] = walloc(word);
+ located = true;
+ break;
+ }
+ while (link[j] >= 0) {
+ j1 = link[j];
+ i = strcmp(word, words[j1]);
+ if (i == 0) {
+ j = j1;
+ located = true;
+ break;
+ }
+ if (i > 0) {
+ wordtop++;
+ if (wordtop > MAXDEFS)
+ error("too many definitions:");
+ link[wordtop] = j1;
+ link[j] = wordtop;
+ j = wordtop;
+ words[wordtop] = walloc(word);
+ located = true;
+ break;
+ }
+ j = j1;
+ }
+ if (located == false) {
+ wordtop++;
+ if (wordtop > MAXDEFS)
+ error("too many definitions:");
+ link[wordtop] = -1;
+ link[j] = wordtop;
+ j = wordtop;
+ words[wordtop] = walloc(word);
+ located = true;
+ break;
+ }
+ }
+ for (p = &line[k]; *p == ' '; p++) ;
+ for (strcpy(dline, p); dline[strlen(dline)-1] == '\\'; ){
+ dline[strlen(dline)-1] = '\n';
+ if (tfgets(line, LINELENGTH, fd) == NULL) break;
+ strcat(dline, line);
+ }
+ defs[j] = walloc(dline);
+ break;
+
+ case 'E': for (p = &line[1]; *p && *p != ' '; p++) {
+ if (*p == 'A')
+ edabbrev = true;
+ else if (*p == 'X')
+ edcapsmcap = true;
+ else if (*p == 'R') {
+ if (isdigit(*(p+1)))
+ ednumrev = atoi(p+1);
+ else
+ ednumrev = 1000;
+ }
+ }
+ break;
+
+ case 'f': foot = true;
+ hyphen = false;
+ break;
+
+ case 'F': specflag = true;
+ break;
+
+ case 'H': hyphen = ordcite = true;
+ break;
+
+ case 'I': for (p = &line[1]; *p == ' '; p++);
+ expnd1(p);
+ incfile(p);
+ break;
+
+ case 'L': loccit = true;
+ break;
+
+ case 'N': for (p = &line[1]; *p == ' '; p++);
+ if (*p == 'A')
+ abbrev = false;
+ else if (*p == 'F')
+ specflag = false;
+ else if (*p == 'H')
+ hyphen = false;
+ else if (*p == 'O')
+ ordcite = false;
+ else if (*p == 'R')
+ numrev = 0;
+ else if (*p == 'S')
+ sort = false;
+ else if (*p == 'X')
+ capsmcap = false;
+ break;
+ case 'O': ordcite = true;
+ break;
+
+ case 'P': onepage = true;
+ break;
+
+ case 'S': sort = true;
+ for (p = &line[1]; *p == ' '; p++) ;
+ strcpy(sortstr, p);
+ for (p=sortstr; *p && *p != ' '; p++);
+ *p=0;
+ break;
+
+ case 'T': for (p = &line[1]; *p == ' '; p++) ;
+ strcpy(trailstr, p);
+ for (p=trailstr; *p && *p != ' '; p++);
+ *p=0;
+ break;
+
+ case 'U': underline = true;
+ break;
+
+ default: fprintf(tfd, "%s\n", line);
+ while (fgets(line, LINELENGTH, fd) != NULL)
+ fputs(line, tfd);
+ fprintf(tfd, "%cmessage {)}", '\\');
+ return;
+ }
+
+ }
+ /* close up */
+ fprintf(tfd, "%cmessage{)}", '\\');
+ fclose(fd);
+}
+
+/* bibwarning - print out a warning message */
+ bibwarning(msg, arg)
+ char *msg, *arg;
+{
+ fprintf(stderr, "`%s', line %d: ", bibfname, biblineno);
+ fprintf(stderr, msg, arg);
+}
+
+/* error - report unrecoverable error message */
+ error(str)
+ char str[];
+{
+ bibwarning("%s\n", str);
+ clnup();
+ exit(1);
+}
+
+#ifdef READWRITE
+/*
+** fixrfd( mode ) -- re-opens the rfd file to be read or write,
+** depending on the mode. Uses a static int to save the current mode
+** and avoid unnecessary re-openings.
+*/
+fixrfd( mode )
+register int mode;
+{
+ static int cur_mode = WRITE; /* rfd open for writing initially */
+
+ if (mode != cur_mode)
+ {
+ rfd = freopen(reffile, ((mode == READ)? "r" : "a"), rfd);
+ cur_mode = mode;
+ if (rfd == NULL)
+ error("Hell! Couldn't re-open reference file");
+ }
+}
+#endif
+
+
+/* tfgets - fgets which trims off newline */
+ char *tfgets(line, n, ptr)
+ char line[];
+ int n;
+ FILE *ptr;
+{ char *p;
+
+ p = fgets(line, n, ptr);
+ if (p == NULL)
+ return(NULL);
+ else
+ for (p = line; *p; p++)
+ if (*p == '\n')
+ *p = 0;
+ return(line);
+}
+
+/* getwrd - place next word from in[i] into out */
+int getwrd(in, i, out)
+ char in[], out[];
+ int i;
+{ int j;
+
+ j = 0;
+ while (in[i] == ' ' || in[i] == '\n' || in[i] == '\t')
+ i++;
+ if (in[i])
+ while (in[i] && in[i] != ' ' && in[i] != '\t' && in[i] != '\n')
+ out[j++] = in[i++];
+ else
+ i = 0; /* signals end of in[i..] */
+ out[j] = 0;
+ return (i);
+}
+
+/* walloc - allocate enough space for a word */
+char *walloc(word)
+ char *word;
+{ char *i, *malloc();
+ i = malloc(1 + strlen(word));
+ if (i == NULL)
+ error("out of storage");
+ strcpy(i, word);
+ return(i);
+}
+
+/* isword - see if character is legit word char */
+int iswordc(c)
+char c;
+{
+ if (isalnum(c) || c == '&' || c == '_')
+ return(true);
+ return(false);
+}
+
+/* expnd1 - expand reference, replacing defined words, scrunching spaces */
+ expnd1(line)
+ char *line;
+{ char line2[REFSIZE], word[LINELENGTH], *p, *q, *w;
+ int replaced, i;
+
+ replaced = true;
+ while (replaced) {
+ replaced = false;
+ p = line;
+ q = line2;
+ while (*p) {
+ if (isalnum(*p)) {
+ for (w = word; *p && iswordc(*p); )
+ *w++ = *p++;
+ *w = 0;
+ for (i = 0; i <= wordtop; i++)
+ if (strcmp(word, words[i]) == 0) {
+ strcpy(word, defs[i]);
+ replaced = true;
+ break;
+ }
+ for (w = word; *w; )
+ *q++ = *w++;
+ }
+ else
+ *q++ = *p++;
+ }
+ *q = 0;
+ p = line;
+ q = line2;
+ while (*q != 0) {
+ if (*q != ' ')
+ *p++ = *q++;
+ else
+ q++;
+ }
+ *p = 0;
+ }
+}
+
+/* expnd2 - expand reference, replacing defined words */
+ expnd2(line)
+ char *line;
+{ char line2[REFSIZE], word[LINELENGTH], *p, *q, *w;
+ int replaced, toolong, i;
+
+ toolong = false; /* flag to indicate reference is too long */
+ replaced = true;
+ while (replaced) {
+ replaced = false;
+ p = line;
+ q = line2;
+ while (*p) {
+ if (*p != '|')
+ if (q - line2 >= REFSIZE-1){
+ toolong = true; /* reference entry is too long */
+ *(q-1) = '\n'; /* make entry end with \n\0 */
+ break;
+ } else
+ *q++ = *p++;
+ else {
+ *p++;
+ for (w = word; *p && *p != '|'; *w++ = *p++);
+ *w = 0;
+ if (locdef(word) == false)
+ fprintf(stderr,"word %s not defined in definition list\n",
+ word);
+ else
+ replaced = true;
+ if (*p == '|')
+ p++;
+ for (w = word; *w; *q++ = *w++)
+ if (q - line2 >= REFSIZE-1){
+ toolong = true; /* reference entry is too long */
+ *(q-1) = '\n'; /* make entry end with \n\0 */
+ break;
+ }
+ }
+ }
+ *q = 0;
+ p = line;
+ q = line2;
+ while (*p++ = *q++);
+ }
+ if(toolong && silent == false) { /* print truncation warning */
+ fprintf(stderr,
+ "Truncated following reference after expanding defined words: \n");
+ fprintf(stderr,"-------------\n%s\n-------------\n",line);
+ }
+}
+
+/* locdef - locate a definition */
+ int locdef(word)
+ char *word;
+{ long int lower, upper, mid, i;
+ int strcmp();
+ char *w, *w1;
+
+ lower = 0;
+ upper = wordtop;
+ if (strcmp(word, words[defpos[lower]]) == 0) {
+ for (w = word, w1 = defs[defpos[lower]]; *w1; *w++ = *w1++);
+ *w = 0;
+ return(true);
+ }
+ if (strcmp(word, words[defpos[upper]]) == 0) {
+ for (w = word, w1 = defs[defpos[upper]]; *w1; *w++ = *w1++);
+ *w = 0;
+ return(true);
+ }
+ while (lower+1 < upper) {
+ mid = (lower + upper)/2;
+ i = strcmp(word, words[defpos[mid]]);
+ if (i == 0) {
+ for (w = word, w1 = defs[defpos[mid]]; *w1; *w++ = *w1++);
+ *w = 0;
+ return(true);
+ }
+ if (i > 0)
+ lower = mid;
+ else
+ upper = mid;
+ }
+ return (false);
+}
+
+/* rdref - read text for an already cited reference */
+ rdref(i, ref)
+ long int i;
+ char ref[REFSIZE];
+{
+ ref[0] = 0;
+#ifdef READWRITE
+ fixrfd( READ ); /* fix access mode of rfd, if nec. */
+#endif
+ fseek(rfd, i, 0);
+ fread(ref, 1, REFSIZE, rfd);
+}
+
+/* breakname - break a name into first and last name */
+ breakname(line, first, last)
+ char line[], first[], last[];
+{ char *p, *q, *r, *t, *f;
+
+ for (t = line; *t != '\n'; t++);
+ for (t--; isspace(*t); t--);
+
+ /* now strip off last name */
+ for (q = t; isspace(*q) == 0 || ((*q == ' ') & (*(q-1) == '\\')); q--) {
+ if (*q == '}') {
+ while (*q != '{') {
+ q--;
+ if (q == line) {
+ fprintf (stderr, "bad brackets in string %s in references\n",
+ line);
+ clnup();
+ exit(1);
+ }
+ }
+ }
+ if (q == line)
+ break;
+ }
+ f = q;
+ if (q != line) {
+ q++;
+ for (; isspace(*f); f--);
+ f++;
+ }
+
+ /* first name is start to f, last name is q to t */
+
+ for (r = first, p = line; p != f; )
+ *r++ = *p++;
+ *r = 0;
+ for (r = last, p = q, t++; q != t; )
+ *r++ = *q++;
+ *r = 0;
+
+}
+
+/* match - see if string1 is a substring of string2 (case independent)*/
+ int match(str1, str2)
+ char str1[], str2[];
+{ int i, j;
+ char a, b;
+
+ for (i = 0; str2[i]; i++) {
+ for (j = 0; str1[j]; j++) {
+ if (isupper(a = str2[i+j]))
+ a = (a - 'A') + 'a';
+ if (isupper(b = str1[j]))
+ b = (b - 'A') + 'a';
+ if (a != b)
+ break;
+ }
+ if (str1[j] == 0)
+ return(true);
+ }
+ return(false);
+}
+
+/* scopy - append a copy of one string to another */
+ char *scopy(p, q)
+ char *p, *q;
+{
+ while (*p++ = *q++)
+ ;
+ return(--p);
+}
+
+/* makecites - make citation strings */
+ makecites(citestr)
+ char *citestr[];
+{ char ref[REFSIZE], tempcite[100], *malloc();
+ int i;
+
+ for (i = 0; i <= numrefs; i++) {
+ rdref(refspos[i], ref);
+ bldcite(tempcite, i, ref);
+ citestr[i] = malloc(2 + strlen(tempcite)); /* leave room for disambig */
+ if (citestr[i] == NULL)
+ error("out of storage");
+ strcpy(citestr[i], tempcite);
+ }
+}
+
+/* sortdefs - make array of pointers to defined words */
+ sortdefs()
+{ long int i, j;
+
+ i = wordtop;
+ for (j = jtop; j >= 0; j = link[j]) {
+ defpos[i] = j;
+ i--;
+ }
+}
+
+/* rcomp1 - revised reference comparison routine for qsort utility */
+ int rcomp1(ap, bp)
+ long int *ap, *bp;
+{ char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD];
+ char alpha1[REFSIZE], alpha2[REFSIZE];
+ char *p, *q, *getfield();
+ int neg, res;
+ int n, m1, m2, num;
+ int getname();
+ char last1[MAXFIELD], last2[MAXFIELD], first1[MAXFIELD], first2[MAXFIELD];
+ int alphabits();
+ char *fstcap();
+
+ rdref(*ap, ref1);
+ rdref(*bp, ref2);
+ for (p = sortstr, q=p; *p ; p=q) {
+ if (*p == '-') {
+ p++;
+ neg = true;
+ }
+ else
+ neg = false;
+ res=0;
+ if (*p == 'A') {
+ p++;
+ if (isdigit(*p))
+ for (num=0; isdigit(*p); p++)
+ num=10*num+(*p-'0');
+ else
+ num=100;
+ q=p;
+ for (n=1; n <= num; n++) {
+ m1=getname (n, last1, first1, ref1);
+ m2=getname (n, last2, first2, ref2);
+ if (m1 == 0 && m2 == 0)
+ break;
+ alphabits(alpha1, last1);
+ alphabits(alpha2, last2);
+/* res = strcmp (fstcap(alphabits(last1)), fstcap(alphabits(last2)));
+ alpha11 = fstcap(alphastring1);
+ alpha21 = fstcap(alphastring2);*/
+ res = strcmp (fstcap(alpha1), fstcap(alpha2));
+ if (res) break;
+ alphabits(alpha1, first1);
+ alphabits(alpha2, first2);
+ res = strcmp (fstcap(alpha1), fstcap(alpha2));
+ if (res != 0) break;
+ }
+ }
+ else {
+ q++;
+ getfield(p, field1, ref1);
+ getfield(p, field2, ref2);
+ res = strcmp (field1, field2);
+ }
+ if (neg)
+ res = - res;
+ if (res != 0)
+ break;
+ }
+ if (res == 0) {
+ if (ap < bp)
+ res = -1;
+ else
+ res = 1;
+ }
+ return(res);
+}
+
+/* alphabits - reduce string to alpha characters */
+ alphabits(stringout, stringin)
+ char *stringin, *stringout;
+{ char *p, *q;
+
+ q = stringout;
+ p = stringin;
+ while (*p) {
+ if (isalpha(*p) || isspace(*p))
+ *q++ = *p++;
+ else if (*p == '{') {
+ for (; *p && *p != '}'; p++);
+ if (*p == 0) {
+ fprintf(stderr, "bad brackets in string %s in references\n",
+ stringin);
+ clnup();
+ exit(1);
+ }
+ else {
+ for (p--; isalpha(*p); p--);
+ for (p++; isalpha(*p); *q++ = *p++);
+ }
+ }
+ else p++;
+ }
+ *q = 0;
+}
+
+/* fstcap - find first capital letter in string */
+ char *fstcap(string)
+ char *string;
+{ char *ptr;
+
+ for(ptr=string; *ptr && (isupper(*ptr) == 0); ptr++);
+ return (ptr);
+}
+
+/* capbrackets - find if string in brackets is capital, also capitalize it */
+ capbrackets(stringout, stringin)
+ char *stringout, *stringin;
+{ char *p, *q;
+ int cap;
+
+ cap = false;
+ q = stringout;
+ p = stringin;
+ for (; *p && *p != '}'; *q++ = *p++);
+ if (*p == 0) {
+ fprintf(stderr, "bad brackets in string %s in references\n",
+ stringin);
+ clnup();
+ exit(1);
+ }
+ *q++ = '}';
+ *q = 0;
+ q--;
+ for (q--; isalpha(*q); q--) {
+ if (isupper (*q))
+ cap = true;
+ else {
+ cap = false;
+ *q = (*q - 'a') + 'A';
+ }
+ }
+ return (cap);
+}
+
+/* undrline - underline successive identical authors */
+ undrline()
+{ char line[REFSIZE], line1[REFSIZE], last[REFSIZE], first[REFSIZE];
+ char ref[REFSIZE];
+ int m, i;
+
+ line1[0] = 0;
+ for (m=numrefs; m >= 0; m--) {
+ rdref(refspos[m], ref);
+ line[0] = 0;
+ for (i=1; getname(i, last, first, ref); i++) {
+ strcat(line, last);
+ strcat(line, first);
+ }
+ if (strcmp(line, line1) == 0)
+ unlmark[m] = true;
+ else
+ unlmark[m] = false;
+ strcpy(line1, line);
+ }
+}
+
+
+/* bldcite - build a single citation string */
+ bldcite(cp, i, ref)
+ char *cp, ref[];
+ int i;
+{ char *p, *q, c, *fp, field[REFSIZE], *getfield(), *aabet(), *nmdt();
+
+ getfield("F", field, ref);
+ if (field[0] != 0 && specflag)
+ for (p = field; *p; p++)
+ *cp++ = *p;
+ else {
+ p = citetemplate;
+ field[0] = 0;
+ while (c = *p++) {
+ if (isalpha(c)) { /* field name */
+ q = getfield(p-1, field, ref);
+ if (q != 0) {
+ p = q;
+ cp=scopy(cp, "\\Citebreak ");
+ for (fp = field; *fp; )
+ *cp++ = *fp++;
+ }
+ }
+ else if (c == '0') { /* empty citation */
+ *cp = '\0';
+ }
+ else if (c == '1') { /* numeric order */
+ sprintf(field, "%d", startflag + i);
+ for (fp = field; *fp; )
+ *cp++ = *fp++;
+ }
+ else if (c == '2') /* alternate alphabetic */
+ cp = aabet(cp, ref);
+ else if (c == '3') /* names */
+ cp = nmdt(cp, ref);
+/* else if (c == '4') here is how to add new styles */
+/* else if (c == '{') {
+ while (*p != '}')
+ if (*p == 0)
+ error("unexpected end of citation template");
+ else
+ *cp++ = *p++;
+ p++;
+ } */
+ else if (c == '<') {
+ while (*p != '>') {
+ if (*p == 0)
+ error("unexpected end of citation template");
+ else
+ *cp++ = *p++;
+ }
+ p++;
+ }
+ else if (c != '@')
+ *cp++ = c;
+ }
+ }
+ *cp++ = 0;
+}
+
+/* alternate alphabetic citation style */
+ char *aabet(cp, ref)
+ char *cp, ref[];
+{ char field[REFSIZE], temp[100], *np, *fp;
+ char string11[80], string12[80], string13[80], string2[80], string3[80];
+ char bracketstring[80];
+ int getname(), i;
+
+ if (getname(1, field, temp, ref)) {
+ fp = field;
+ for (np = string11; *fp; fp++) {
+ if (isupper(*fp)) {
+ *np++ = *fp;
+ break;
+ }
+ else if (*fp == '{') {
+ if (capbrackets(bracketstring, fp) == 0)
+ for (; *fp != '}'; fp++);
+ else {
+ for (; *fp != '}'; *np++ = *fp++);
+ *np++ = '}';
+ break;
+ }
+ }
+ }
+ if (*fp) fp++;
+ *np = 0;
+ for (np = string12; *fp && isalpha(*fp) == 0 && *fp != '{';
+ *np++ = *fp++);
+ if (*fp != '{')
+ *np++ = *fp;
+ else {
+ capbrackets(bracketstring, fp);
+ for (; *fp != '}'; *np++ = *fp++);
+ *np++ = '}';
+ }
+ if (*fp) fp++;
+ *np = 0;
+ for (np = string13; *fp && isalpha(*fp) == 0 && *fp != '{';
+ *np++ = *fp++);
+ if (*fp != '{')
+ *np++ = *fp;
+ else {
+ capbrackets(bracketstring, fp);
+ for (; *fp != '}'; *np++ = *fp++);
+ *np++ = '}';
+ }
+ *np = 0;
+ }
+ if (getname(2, field, temp, ref) == 0) {
+ strcpy (field, string11);
+ strcat (field, string12);
+ strcat (field, string13);
+ }
+ else {
+ fp = field;
+ for (np = string2; *fp; fp++) {
+ if (isupper(*fp)) {
+ *np++ = *fp;
+ break;
+ }
+ if (*fp == '{') {
+ if (capbrackets(bracketstring, fp) == 0)
+ for (; *fp != '}'; fp++);
+ else {
+ for (; *fp != '}'; *np++ = *fp++);
+ *np++ = '}';
+ break;
+ }
+ }
+ }
+ *np = 0;
+ if (getname(3, field, temp, ref) == 0) {
+ strcpy (field, string11);
+ strcat (field, string12);
+ strcat (field, string2);
+ }
+ else {
+ fp = field;
+ for (np = string3; *fp; fp++) {
+ if (isupper(*fp)) {
+ *np++ = *fp;
+ break;
+ }
+ if (*fp == '{') {
+ if (capbrackets(bracketstring, fp) == 0)
+ for (; *fp != '}'; fp++);
+ else {
+ for (; *fp != '}'; *np++ = *fp++);
+ *np++ = '}';
+ break;
+ }
+ }
+ }
+ *np = 0;
+ strcpy (field, string11);
+ strcat (field, string2);
+ strcat (field, string3);
+ }
+ }
+ for (i=0; field[i]; i++)
+ *cp++ = field[i];
+ return (cp);
+}
+
+/* names style
+ if 1 author - last name date
+ if 2 authors - last name and last name date
+ if 3 authors - last name, last name and last name date
+ if 4 or more authors - last name et al. date */
+ char *nmdt(cp, ref)
+ char *cp, ref[];
+{ char name1[100], name2[100], name3[100], temp[100], *fp;
+ int getname();
+
+ if (getname(1, name1, temp, ref)) {
+ for (fp = name1; *fp; )
+ *cp++ = *fp++;
+ if (getname(4, name3, temp, ref)) {
+ for (fp = " et al."; *fp; )
+ *cp++ = *fp++;
+ }
+ else if (getname(2, name2, temp, ref)) {
+ if (getname(3, name3, temp, ref)) {
+ for (fp = "\\Namecomma "; *fp; )
+ *cp++ = *fp++;
+ for (fp = name2; *fp; )
+ *cp++ = *fp++;
+ for (fp = "\\Nameandd "; *fp; )
+ *cp++ = *fp++;
+ for (fp = name3; *fp; )
+ *cp++ = *fp++;
+ }
+ else {
+ for (fp = "\\Nameand "; *fp; )
+ *cp++ = *fp++;
+ for (fp = name2; *fp; )
+ *cp++ = *fp++;
+ }
+ }
+ }
+return(cp);
+}
+
+/* getfield - get a single field from reference */
+ char *getfield(ptr, field, ref)
+ char *ptr, field[], ref[];
+{ char *p, *q, temp[100];
+ int n, len, i, getname();
+
+ field[0] = 0;
+ if (*ptr == 'A')
+ getname(1, field, temp, ref);
+ else
+ for (p = ref; *p; p++)
+ if (*p == '%' && *(p+1) == *ptr) {
+ for (p = p + 2; *p == ' '; p++)
+ ;
+ for (q = field; (*p != '\n') && (*p != '\0'); )
+ *q++ = *p++;
+ *q = 0;
+ break;
+ }
+ n = 0;
+ len = strlen(field);
+ if (*++ptr == '-') {
+ for (ptr++; isdigit(*ptr); ptr++)
+ n = 10 * n + (*ptr - '0');
+ if (n > len)
+ n = 0;
+ else
+ n = len - n;
+ for (i = 0; field[i] = field[i+n]; i++)
+ ;
+ }
+ else if (isdigit(*ptr)) {
+ for (; isdigit(*ptr); ptr++)
+ n = 10 * n + (*ptr - '0');
+ if (n > len)
+ n = len;
+ field[n] = 0;
+ }
+
+ if (*ptr == 'u') {
+ ptr++;
+ for (p = field; *p; p++)
+ if (islower(*p))
+ *p = (*p - 'a') + 'A';
+ }
+ else if (*ptr == 'l') {
+ ptr++;
+ for (p = field; *p; p++)
+ if (isupper(*p))
+ *p = (*p - 'A') + 'a';
+ }
+ return(ptr);
+}
+
+/* getname - get the nth name field from reference, breaking into
+ first and last names */
+ int getname(n, last, first, ref)
+ int n;
+ char last[], first[], ref[];
+{ char *p;
+ int m;
+
+ last[0]='\0';
+ first[0]='\0';
+ m = n;
+ for (p = ref; *p; p++)
+ if (*p == '%' & *(p+1) == 'A') {
+ n--;
+ if (n == 0) {
+ for (p = p + 2; *p == ' '; p++) ;
+ breakname(p, first, last) ;
+ return(true);
+ }
+ }
+
+ if (n == m) /* no authors, try editors */
+ for (p = ref; *p; p++)
+ if (*p == '%' & *(p+1) == 'E') {
+ n--;
+ if (n == 0) {
+ for (p = p + 2; *p == ' '; p++) ;
+ breakname(p, first, last) ;
+ return(true);
+ }
+ }
+
+ if (n == m && n == 1) { /* no editors, either, try institution */
+ first[0] = last[0] = '\0';
+ getfield("I", last, ref);
+ if (last[0] != '\0')
+ return(true);
+ }
+
+ return(false);
+}
+
+/* disambiguate - compare adjacent citation strings, and if equal, add
+ single character disambiguators */
+ disambiguate()
+{ int i, j;
+ char adstr[2];
+
+ for (i = 0; i < numrefs; i = j) {
+ j = i + 1;
+ if (strcmp(citestr[i], citestr[j])==0) {
+ adstr[0] = 'a'; adstr[1] = 0;
+ for (j = i+1; strcmp(citestr[i], citestr[j]) == 0; j++) {
+ adstr[0] = 'a' + (j-i);
+ strcat(citestr[j], adstr);
+ if (j == numrefs)
+ break;
+ }
+ adstr[0] = 'a';
+ strcat(citestr[i], adstr);
+ }
+ }
+}
+
+
+/* bldname - build a name field
+ doing abbreviations, reversals, and caps/small caps
+*/
+ bldnm1(first, last, name, reverse)
+ char *first, *last, name[];
+ int reverse;
+{
+ char newfirst[120], newlast[120], *p, *q, *f, *l, *scopy();
+ int flag;
+
+ if (abbrev) {
+ p = first;
+ q = newfirst;
+ flag = false;
+ while (*p) {
+ while (*p == ' ')
+ p++;
+ if (*p == 0)
+ break;
+ if (isupper(*p)) {
+ if (flag) /* between initial gap */
+ q = scopy(q, "\\Initgap ");
+ flag = true;
+ *q++ = *p;
+ q = scopy(q, "\\Initper ");
+ }
+ if (*++p == '.')
+ p++;
+ else while (*p != 0 && ! isspace(*p))
+ p++;
+ }
+ *q = 0;
+ f = newfirst;
+ }
+ else
+ f = first;
+
+ if (capsmcap) {
+ p = last;
+ q = newlast;
+ flag = 0; /* 1 - printing cap, 2 - printing small */
+ while (*p)
+ if (islower(*p)) {
+ if (flag != 2)
+ q = scopy(q, "\\bgroup\\Smallcapsfont ");
+ flag = 2;
+ *q++ = (*p++ - 'a') + 'A';
+ }
+ else {
+ if (flag == 2)
+ q = scopy(q, "\\egroup ");
+ flag = 1;
+ *q++ = *p++;
+ }
+ if (flag == 2)
+ q = scopy(q, "\\egroup ");
+ *q = 0;
+ l = newlast;
+ }
+ else
+ l = last;
+
+ if (f[0] == 0)
+ sprintf(name, "%s\n", l);
+ else if (reverse)
+ sprintf(name, "%s%cRevcomma %s\n", l, '\\', f);
+ else
+ sprintf(name, "%s %s\n", f, l);
+}
+
+/* capssmallcaps - put field in capssmallcaps */
+ capssmallcaps(stringout, stringin)
+ char *stringout, *stringin;
+{ char *p, *q, *scopy();
+ int flag, bflag;
+ char bracketfield[REFSIZE];
+
+ p = stringin;
+ q = stringout;
+ *q = 0;
+ flag = 0; /* 1 - printing cap, 2 - printing small */
+ while (*p) {
+ if (*p == '\\')
+ *p++;
+ if (*p == ' ') {
+ if (flag == 2)
+ q = scopy(q, "\\egroup{}");
+ flag = 1;
+/* *q++ = '\\';*/
+ *q++ = ' ';
+ p++;
+ }
+ if (*p == '~') {
+ if (flag == 2)
+ q = scopy(q, "\\egroup{}");
+ flag = 1;
+ *q++ = *p++;
+ }
+ if (*p == '{')
+ bflag = capbrackets(bracketfield, p);
+ else
+ bflag = 1;
+ if (islower(*p) || bflag == 0) {
+ if (flag != 2)
+ q = scopy(q, "\\bgroup\\Smallcapsfont ");
+ flag = 2;
+ if (*p == '{') {
+ q = scopy(q, bracketfield);
+ for (; *p != '}'; p++);
+ p++;
+ }
+ else
+ *q++ = (*p++ - 'a') + 'A';
+ }
+ else {
+ if (flag == 2)
+ q = scopy(q, "\\egroup{}");
+ flag = 1;
+ if (*p == '{') {
+ q = scopy(q, bracketfield);
+ for (; *p != '}'; p++);
+ p++;
+ }
+ else
+ *q++ = *p++;
+ }
+ }
+ if (flag == 2)
+ q = scopy(q, "\\egroup{}");
+ *q = 0;
+}
+
+ bldname(first, last, name, reverse, capsmcap)
+ char *first, *last, name[];
+ int reverse, capsmcap;
+{
+ char newfirst[120], newlast[120], *p, *q, *f, *f1, *l, *scopy();
+ char newnewfirst[120];
+ char bracketfield[20];
+ int flag;
+ int hflag, bflag;
+
+ if (abbrev) {
+ p = first;
+ q = newfirst;
+ flag = false;
+ hflag = false;
+ bflag = false;
+ while (*p) {
+ while (*p == ' ')
+ p++;
+ if (*p == '{')
+ bflag = capbrackets(bracketfield, p);
+ if (isupper(*p) || bflag) {
+ if (flag && hflag) /* between initial gap */
+ q = scopy(q, "\\Initgap ");
+ flag = true;
+ if (bflag) {
+ for (; *p != '}'; *q++ = *p++);
+ bflag = false;
+ }
+ *q++ = *p;
+ for (p++;; p++) {
+ if (isupper(*p)) {
+ hflag = true;
+ break;
+ }
+ else if (*p == '-' || *p == '\'') {
+ hflag = false;
+ *q++ = *p++;
+ break;
+ }
+ else if (*p == '.' ) {
+ hflag = true;
+ q = scopy(q, "\\Initper ");
+ p++;
+ break;
+ }
+ else if (*p == ' ' ) {
+ hflag = true;
+ q = scopy(q, "\\Initper ");
+ p++;
+ break;
+ }
+ else if (*p == '~') {
+ hflag = true;
+ q = scopy(q, "\\Initper ");
+ p++;
+ break;
+ }
+ else if (*p == 0) {
+ q = scopy(q, "\\Initper ");
+ break;
+ }
+ else if (*p == '{') {
+ bflag = capbrackets(bracketfield, p);
+ if (bflag) break;
+ else
+ for (; *p != '}'; p++);
+ }
+ }
+ }
+ else
+ *q++ = *p++;
+ }
+ *q = 0;
+ f1 = newfirst;
+ }
+ else
+ f1 = first;
+
+ if (capsmcap) {
+ capssmallcaps(newlast,last);
+ l = newlast;
+ if (abbrev == 0) {
+ capssmallcaps(newnewfirst,f1);
+ f = newnewfirst;
+ }
+ else
+ f = f1;
+ }
+ else {
+ f = f1;
+ l = last;
+ }
+ if (f[0] == 0)
+ sprintf(name, "%s\n", l);
+ else if (reverse)
+ sprintf(name, "%s%cRevcomma %s\n", l, '\\', f);
+ else
+ sprintf(name, "%s %s\n", f, l);
+}
+
+/* prtauth - print author or editor field */
+ prtauth(c, line, num, max, ofd, abbrev, capsmcap, numrev)
+ char c, *line;
+ int num, max, abbrev, capsmcap, numrev;
+ FILE *ofd;
+{ char first[LINELENGTH], last[LINELENGTH];
+ char *s1;
+
+ if (num <= numrev || abbrev || capsmcap) {
+ breakname(line, first, last);
+ bldname(first, last, line, num <= numrev, capsmcap);
+ }
+ for (s1=line;*s1!='\0';s1++) if (*s1=='\n') *s1='\0';
+ if (num == 1) {
+ fprintf(ofd, "}%c\n%cdef%c%ctest{ }", '\%', '\\', '\\', c);
+ if (index(trailstr, c))
+ fprintf(ofd, "%cdef%c%ctrail{%c}",
+ '\\', '\\', c, line[strlen(line)-2]);
+ fprintf(ofd, "%cdef%c%cstr{%s",
+ '\\', '\\', c, line);
+ }
+ else if (num < max)
+ fprintf(ofd, "%c\n %c%ccomma %s", '\%', '\\', c, line);
+ else if (max == 2)
+ fprintf(ofd, "%c\n %c%cand %s", '\%', '\\', c, line);
+ else
+ fprintf(ofd, "%c\n %c%candd %s", '\%', '\\', c, line);
+}
+
+/* doline - actually print out a line of reference information */
+ doline(c, line, numauths, maxauths, numeds, maxeds,
+ numrevs, maxrevs, numtrans, maxtrans, ofd)
+ char c, *line;
+ int numauths, maxauths, numeds, maxeds;
+ int numrevs, maxrevs, numtrans, maxtrans;
+ FILE *ofd;
+{
+ char *s1;
+ char *dbldash();
+ char line1[REFSIZE];
+
+ switch(c) {
+ case '\\':
+ case '\%':
+ for (s1=line;*s1!='\0';s1++)
+ if (*s1=='\n') *s1='\0';
+ fprintf(ofd, "}%c\n%c%s{", '\%', c , line);
+ break;
+
+ case 'A':
+ prtauth(c, line, numauths, maxauths, ofd, abbrev, capsmcap, numrev);
+ break;
+
+ case 'E':
+ if (maxauths)
+ prtauth(c, line, numeds, maxeds, ofd, edabbrev, edcapsmcap,
+ ednumrev);
+ else
+ prtauth(c, line, numeds, maxeds, ofd, abbrev, capsmcap, numrev);
+ break;
+
+ case 'a':
+ prtauth(c, line, numtrans, maxtrans, ofd, edabbrev, edcapsmcap,
+ ednumrev);
+ break;
+
+ case 'e':
+ prtauth(c, line, numrevs, maxrevs, ofd, edabbrev, edcapsmcap,
+ ednumrev);
+ break;
+
+ case 'P':
+ case 'p':
+ fprintf(ofd, "}%c\n%cdef%c%ctest{ }", '\%', '\\', '\\', c);
+ if (onepage) {
+ opage(line);
+ fprintf(ofd, "%cdef%c%ccnt{}", '\\', '\\', c);
+ }
+ else {
+ if (index (line, '-')) {
+ line = dbldash(line);
+ fprintf(ofd, "%cdef%c%ccnt{ }", '\\', '\\', c);
+ }
+ else
+ fprintf(ofd, "%cdef%c%ccnt{}", '\\', '\\', c);
+ }
+ if (index(trailstr, c))
+ fprintf(ofd, "%cdef%c%ctrail{%c}%c\n", '\\', '\\', c,
+ line[strlen(line)-2], '\%');
+ for (s1 = line; *s1 != '\0'; s1++)
+ if (*s1=='\n') *s1='\0';
+ fprintf(ofd, "%cdef%c%cstr{%s", '\\', '\\', c,
+ line);
+ break;
+
+ case 'F':
+ case 'K': break;
+
+ case 'I':
+ if (numauths == 0 && numeds == 0 && capsmcap) {
+ capssmallcaps(line1, line);
+ strcpy(line, line1);
+ }
+
+ default:
+ fprintf(ofd, "}%c\n%cdef%c%ctest{ }", '\%', '\\', '\\', c);
+ if (index(trailstr, c))
+ fprintf(ofd, "%cdef%c%ctrail{%c}", '\\', '\\', c,
+ line[strlen(line)-2]);
+ for (s1=line;*s1!='\0';s1++)
+ if (*s1=='\n') *s1='\0';
+ fprintf(ofd, "%cdef%c%cstr{%s",
+ '\\', '\\', c, line);
+ }
+}
+
+/* dbldash - double the hyphen in the P field (see below)*/
+ char *dbldash(line)
+ char *line;
+{ char *p;
+ char newline[120];
+
+ for (p = newline; *line && *line != '-'; *p++ = *line++);
+ if (*line == 0) return (line);
+ if (*++line != '-')
+ *p++ = '-';
+ *p++ = '-';
+ for (*p = *line; *line; *p++ = *line++);
+ *p='\0';
+ return (newline);
+}
+
+/* following works on some machines where above fails
+char *dbldash(line)
+char *line;
+{ char *p;
+ static char newline[120];
+
+ for (p = newline; *p = *line; ++p, ++line)
+ if (line[0] == '-' && line[1] != '-')
+ *++p = '-';
+ return(newline);
+} */
+
+/* opage - print only first page number */
+ int opage(line)
+ char *line;
+{ char *p;
+
+ for (p = line; *p && *p != '-'; *p++);
+ *p=0;
+}
+
+/* dumpref - dump reference number i */
+ dumpref(i, ofd)
+ int i;
+ FILE *ofd;
+{ char ref[REFSIZE], *p, line[REFSIZE];
+ int numauths, maxauths, numeds, maxeds;
+ int numrevs, maxrevs, numtrans, maxtrans;
+
+ fprintf(ofd, "%cbgroup%cResetstrings%c\n", '\\', '\\' , '\%');
+ rdref(refspos[i], ref);
+ maxauths = maxeds = maxrevs = maxtrans = 0;
+ numauths = numeds = numrevs = numtrans = 0;
+ for (p = ref; *p; p++)
+ if (*p == '%')
+ if (*(p+1) == 'A') maxauths++;
+ else if (*(p+1) == 'E') maxeds++;
+ else if (*(p+1) == 'a') maxtrans++;
+ else if (*(p+1) == 'e') maxrevs++;
+ if (loccit) {
+ if (locflag[i])
+ fprintf(ofd, "%cdef%cLoccittest{ }", '\\', '\\');
+ else
+ fprintf(ofd, "%cdef%cLoccittest{}", '\\', '\\');
+ if (ibidflag[i])
+ fprintf(ofd, "%cdef%cIbidtest{ }", '\\', '\\');
+ else
+ fprintf(ofd, "%cdef%cIbidtest{}", '\\', '\\');
+ }
+ else
+ fprintf(ofd, "%cdef%cLoccittest{}", '\\', '\\');
+ if (abbrev)
+ fprintf(ofd, "%cdef%cAbbtest{ }", '\\', '\\');
+ else
+ fprintf(ofd, "%cdef%cAbbtest{}", '\\', '\\');
+ if (capsmcap)
+ fprintf(ofd, "%cdef%cCapssmallcapstest{ }", '\\', '\\');
+ else
+ fprintf(ofd, "%cdef%cCapssmallcapstest{}", '\\', '\\');
+ if (edabbrev)
+ fprintf(ofd, "%cdef%cEdabbtest{ }", '\\', '\\');
+ else
+ fprintf(ofd, "%cdef%cEdabbtest{}", '\\', '\\');
+ if (edcapsmcap)
+ fprintf(ofd, "%cdef%cEdcapsmallcapstest{ }", '\\', '\\');
+ else
+ fprintf(ofd, "%cdef%cEdcapsmallcapstest{}", '\\', '\\');
+ if (underline)
+ fprintf(ofd, "%cdef%cUnderlinetest{ }%c\n", '\\', '\\', '\%');
+ else
+ fprintf(ofd, "%cdef%cUnderlinetest{}%c\n", '\\', '\\', '\%');
+ fprintf(ofd, "%cdef%cNoArev{%d}%cdef%cNoErev{%d}%cdef%cAcnt{%d}",
+ '\\', '\\', numrev, '\\', '\\', ednumrev, '\\', '\\', maxauths);
+ fprintf(ofd, "%cdef%cEcnt{%d}%cdef%cacnt{%d}%cdef%cecnt{%d}%c\n",
+ '\\', '\\', maxeds, '\\', '\\',
+ maxtrans, '\\', '\\', maxrevs, '\%');
+ fprintf(ofd, "%cdef%cFtest{ }", '\\', '\\');
+ if (index(trailstr, 'F'))
+ fprintf(ofd, "%cdef%c%ctrail{%c}", '\\', '\\', 'F',
+ citestr[i][strlen(citestr[i])-1]);
+ fprintf(ofd, "%cdef%cFstr{%s", '\\', '\\',
+ citestr[i]);
+ fseek(rfd, (long) refspos[i], 0);
+ while (fgets(line, REFSIZE, rfd) != NULL) {
+ if (line[0] == 0) break;
+ else if (line[0] == '%') {
+ for (p = &line[2]; *p == ' '; p++);
+ if (line[1] == 'A') numauths++;
+ else if (line[1] == 'E') numeds++;
+ else if (line[1] == 'a') numtrans++;
+ else if (line[1] == 'e') numrevs++;
+
+ doline(line[1], p, numauths, maxauths, numeds, maxeds,
+ numrevs, maxrevs, numtrans, maxtrans, ofd);
+ }
+ else if (line[0] == '\\')
+ fprintf(ofd, "}%c\n%s{", '\%', line);
+ else fprintf(ofd, "%s", line);
+ }
+ if (underline && unlmark[i-1]) {
+ if (maxauths) fprintf (ofd, "}%c\n%cdef%cAstr{%cUnderlinemark", '\%',
+ '\\', '\\', '\\');
+ else if (maxeds) fprintf (ofd, "}%c\n%cdef%cEstr{%cUnderlinemark", '\%',
+ '\\', '\\', '\\');
+ else fprintf (ofd, "}%c\n%cdef%cIstr{%cUnderlinemark", '\%', '\\',
+ '\\', '\\');
+ }
+ fprintf(ofd, "}%c\n%cRefformat%cegroup%c\n", '\%', '\\', '\\', '\%');
+ if ((!foot) && (!c0)) fprintf(ofd, "\n");
+}
diff --git a/biblio/tib/src/tibdex.c b/biblio/tib/src/tibdex.c
new file mode 100644
index 0000000000..878d9eafd4
--- /dev/null
+++ b/biblio/tib/src/tibdex.c
@@ -0,0 +1,239 @@
+/*
+ Tibdex - makes an inverted index for tib
+ a slight modification of Invert of bib
+
+ input: records of lines, separated by blank lines
+ output: key:file1 start/length ... start/length:file2 start/length ...
+
+Note to non-unix users:
+ This program uses a unix command "sort" which sorts records in a file
+ "tmp_file" with the following sort key:
+ ASCII sort on the first field (fields are separated by spaces),
+ ASCII sort on the second field,
+ numeric sort on the third record,
+ numeric sort on the fourth record,
+ removing duplicates, and then writes to the same file. The use of "sort"
+ is isolated by the "#define SORT_IT" statement just below. If "sort"
+ is unavailable, replace the sort in the definition of "SORT_IT" by some
+ equivalent sort. If the format of "SORT_IT" is unacceptable, modify
+ appropriately the one place further below where "SORT_IT" is used.
+ It may not be necessary to remove duplicates.
+
+*/
+
+#define SORT_IT \
+ sprintf(sortcmd,"sort -u +0 -1 +1 -2 +2n -3 +3n %s -o %s",tmp_file,tmp_file);\
+ system(sortcmd);
+
+
+#include "stdio.h"
+#include "tib.h"
+#define isnull(x) (*(x) == NULL)
+#define makelow(c) ('A'<=(c) && (c)<='Z' ? (c)-'A'+'a' : c)
+
+char headerline[240] = " ";/* header line -- list of files */
+int max_kcnt = 100; /* max number of keys */
+int max_klen = 6; /* max length of keys */
+char *ignore = /* string of line starts to ignore */
+ "CNOPVcnopv\\\%";
+char *common = COMFILE; /* name of file of common words */
+char *INDEX = INDXFILE; /* name of output file */
+char tmp_file[120]; /* name of temporary file */
+char dirsp2[]=DIRSEP; /* directory separator character */
+char optch2[]=OPTCH; /* option character on call */
+int silent = 0; /* 0 => statistics printed */
+ /* 1 => no statisitics printed */
+
+long int nextrecord(), recsize(), nextline();
+char sortcmd[MAXSTR];
+
+int argc;
+char **argv;
+
+main(argcount,arglist)
+int argcount;
+char **arglist;
+{ char filename[MAXSTR], *pcom, *getenv(), *ptemp;
+ FILE *input, *output;
+ long int start,length;
+ char word[MAXSTR];
+ int kcnt;
+ char tag_line[MAXSTR];
+ char argchk[3];
+
+ long int records = 0; /* number of records read */
+ long int keys = 0; /* number of keys read (occurences) */
+ long int distinct; /* number of distinct keys */
+ long int shorten();
+ int i, strcmp();
+
+ /* header */
+ for (i = 1; i < argcount; i++) {
+ strcpy(argchk,OPTCH);
+ strcat(argchk,"z");
+ if (strcmp(arglist[i],argchk) == 0)
+ silent = true;
+ }
+ if (silent == false)
+ fprintf (stderr, "Tibdex -- version %s, released %s.\n", VERSION, RDATE);
+
+ /* get file names from environment */
+ pcom = getenv("COMFILE");
+ if (pcom != NULL)
+ strcpy(common,pcom);
+ ptemp = getenv("TMPDIR");
+ if (ptemp != NULL) {
+ strcpy(tmp_file,ptemp);
+ strcat(tmp_file,dirsp2);
+ strcat(tmp_file,"tibdXXXXXX");
+ }
+ else
+ strcpy(tmp_file,INVTEMPFILE);
+
+ argc= argcount-1;
+ argv= arglist+1;
+ mktemp(tmp_file);
+ output= fopen(tmp_file,"w");
+ if (output == NULL) {
+ fprintf(stderr, "tibdex: can't open temporary output file\n");
+ exit(1);
+ }
+
+ for ( flags() ; argc>0 ; argc--, argv++ ,flags() )
+ { /* open input file */
+ strcpy(filename, *argv);
+ input = fopen(filename, "r");
+ if (input == NULL) {
+ strcat(filename, ".ref");
+ input=fopen(filename, "r");
+ if (input == NULL) {
+ fprintf(stderr, "can't open %s or %s\n", *argv, filename);
+ exit(1);
+ }
+ }
+ strcat(headerline, " ");
+ strcat(headerline, filename);
+ start= 0L;
+ length= 0L;
+
+ for(;;) /* each record */
+ { /* find start of next record (exit if none) */
+ start= nextrecord(input,start+length);
+ if (start==EOF) break;
+ records++;
+ kcnt= 0;
+ length= recsize(input,start);
+ sprintf(tag_line, " %s %D %D\n", filename, start, length);
+
+ while (ftell(input) < start+length && kcnt < max_kcnt)
+ { getword(input,word,ignore);
+ makekey(word,max_klen,common);
+ if (!isnull(word))
+ { fputs(word,output); fputs(tag_line,output);
+ kcnt++; keys++;
+ }
+ }
+ }
+ fclose(input);
+ }
+ fclose(output);
+
+ SORT_IT
+
+ distinct = shorten(tmp_file,INDEX);
+ if( silent == 0 )
+ fprintf(stderr,
+ "%D documents %D distinct keys %D key occurrences\n",
+ records, distinct, keys);
+}
+
+
+
+/* Flag Meaning Default
+ -ki Keys per record 100
+ -li max Length of keys 6
+ -%str ignore lines that begin with %x CNOPVXcnopv
+ where x is in str
+ str is a seq of chars
+ -cfile file contains Common words /??????/common
+ do not use common words as keys
+ -pfile name of output file INDEX
+ -s do not print statistics statistics printed
+*/
+
+#define operand (strlen(*argv+2)==0 ? (argv++,argc--,*argv) : *argv+2)
+
+flags()
+{ for (; argc>0 && *argv[0]==optch2[0]; argc--,argv++)
+ { switch ((*argv)[1])
+ { case 'k': max_kcnt= atoi(operand);
+ break;
+ case 'l': max_klen= atoi(operand);
+ break;
+ case 'c': common= operand;
+ break;
+ case '%': ignore= *argv+2;
+ break;
+ case 'p': INDEX= operand;
+ break;
+ case 'z': silent= 1;
+ break;
+ default: fprintf(stderr, "unknown flag '%s'\n", *argv);
+ }
+ }
+}
+
+
+/* shorten(inf,outf): file "inf" consists of lines of the form:
+ key file start length
+ sorted by key and file. replace lines with the same key
+ with one line of the form:
+ key:file1 start/length ... start/length:file2 start/length ...
+ rename as file "outf"
+ returns number of lines in output
+*/
+long shorten(inf,outf)
+char *inf, *outf;
+{ FILE *in, *out;
+ char line[MAXSTR];
+ char key[MAXSTR], newkey[MAXSTR],
+ file[MAXSTR], newfile[MAXSTR];
+ long int start, length;
+ long int lines = 0;
+
+ strcpy(file,"");
+ strcpy(key,"");
+ in= fopen(inf, "r");
+ out= fopen(outf, "w");
+ if (in==NULL || out==NULL)
+ { fprintf(stderr, "tibdex: error in opening file for compression\n");
+ return(1);
+ }
+
+ fputs(headerline,out);
+ fprintf(out, "\n");
+ getline(in,line);
+ sscanf(line,"%s%s%ld%ld", key, file, &start, &length);
+ fprintf(out, "%s :%s %D/%D", key, file, start, length);
+ for ( getline(in, line) ; !feof(in); getline(in, line))
+ { sscanf(line,"%s%s%ld%ld", newkey, newfile, &start, &length);
+ if (strcmp(key,newkey)!=0)
+ { strcpy(key, newkey);
+ strcpy(file, newfile);
+ fprintf(out, "\n%s :%s %D/%D", key, file, start, length);
+ lines++;
+ }
+ else if (strcmp(file,newfile)!=0)
+ { strcpy(file,newfile);
+ fprintf(out, ":%s %D/%D", file, start, length);
+ }
+ else
+ fprintf(out, " %D/%D", start, length);
+ }
+ fprintf(out, "\n");
+ lines++;
+
+ fclose(in); fclose(out);
+ unlink(inf);
+ return (lines);
+}
diff --git a/biblio/tib/src/tiblist.c b/biblio/tib/src/tiblist.c
new file mode 100644
index 0000000000..0072f5d247
--- /dev/null
+++ b/biblio/tib/src/tiblist.c
@@ -0,0 +1,219 @@
+/*
+ Tiblist - list references for tib system
+
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include "tib.h"
+#define MAXLIST 2000 /* maximum number of references that can be listed */
+#define getch(c,fd) (c = getc(fd))
+
+FILE *tfd; /* temporary file position */
+char tmp_file[120]; /* temporary file (see tib.h) */
+FILE *rfd; /* reference file position */
+char reffile[120]; /* temporary file (see tib.h) */
+long int refspos[MAXLIST]; /* references temporary file, seek positions */
+long int rend = 1; /* last used position in reference file */
+int numrefs = -1; /* number of references */
+char *citestr[MAXLIST]; /* citation strings */
+extern int sort; /* see if things are to be sorted */
+int unlmark[MAXLIST]; /* underline flags */
+extern char bibfname[], citetemplate[];
+extern int biblineno;
+extern int underline, silent, stndout;
+extern char dirsp2[], optch2[], suffix[];
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{ int i, rcomp1();
+ char *outname;
+ char *outfname();
+ int undrline();
+ FILE *ofd;
+ int c;
+ int strcmp();
+ char *pdefst, *getenv(), *ptemp, argchk[3];
+
+ /* header */
+ for (i = 1; i < argc; i++) {
+ strcpy(argchk,OPTCH);
+ strcat(argchk,"z");
+ if (strcmp(argv[i],argchk) == 0)
+ silent = true;
+ strcpy(argchk,OPTCH);
+ strcat(argchk,"|");
+ if (strcmp(argv[i],argchk) == 0)
+ silent = true;
+ }
+ if (silent == false)
+ fprintf (stderr, "Tiblist -- version %s, released %s.\n",
+ VERSION, RDATE);
+
+ /* get file names from environment */
+
+ ptemp = getenv("TMPDIR");
+ if (ptemp != NULL) {
+ strcpy(reffile,ptemp);
+ strcat(reffile,dirsp2);
+ strcat(reffile,"tibrXXXXXX");
+ strcpy(tmp_file,ptemp);
+ strcat(tmp_file,dirsp2);
+ strcat(tmp_file,"tibpXXXXXX");
+ }
+ else {
+ strcat(reffile,TMPREFFILE);
+ strcat(tmp_file,TMPTEXTFILE);
+ }
+
+ mktemp(reffile);
+ rfd = fopen(reffile,"w+");
+ if (rfd == NULL)
+ error("can't open temporary reference file");
+ putc('x', rfd); /* put garbage in first position */
+ mktemp(tmp_file);
+ tfd = fopen(tmp_file,"w");
+ if (tfd == NULL)
+ error("can't open temporary output file");
+
+ strcpy(suffix,".ref");
+ pdefst = getenv("DEFSTYLE");
+ if (pdefst == NULL)
+ doargs(argc, argv, DEFSTYLE);
+ else
+ doargs(argc, argv, pdefst);
+
+ if (silent == 0)
+ fprintf(stderr, "Processing reference list ...\n");
+ if (sort)
+ qsort(refspos, numrefs+1, sizeof(long), rcomp1);
+ makecites(citestr);
+ if (underline)
+ undrline();
+ if (citetemplate[0] != '0')
+ disambiguate();
+
+
+ /*
+ reopen temporaries
+ */
+
+ fclose(tfd);
+ tfd = fopen(tmp_file,"r");
+ if (tfd == NULL)
+ error("can't open temporary output file for reading");
+
+ if (stndout == true && bibfname != "<stdin>") {
+ while (getch(c,tfd) != EOF)
+ putc(c, stdout);
+ for (i = 0; i <= numrefs; i++)
+ dumpref(i, stdout);
+ fprintf(stdout, "%cbye\n", '\\');
+ }
+ else {
+ outname = outfname (bibfname);
+ ofd = fopen (outname, "w");
+ if (ofd == NULL) {
+ fprintf(stderr,"can't open %s\n", outname);
+ clnup();
+ exit(1);
+ }
+ else {
+ if (silent == 0)
+ fprintf(stderr, "Writing output file ...\n");
+ while (getch(c,tfd) != EOF)
+ putc(c, ofd);
+ for (i = 0; i <= numrefs; i++)
+ dumpref(i, ofd);
+ fprintf(ofd, "%cbye\n", '\\');
+ fclose (ofd);
+ fprintf (stderr,"Output of tiblist in %s.\n", outname);
+ }
+ }
+ clnup();
+ exit(0);
+}
+
+ /* clean up */
+ clnup()
+{
+ unlink(tmp_file);
+ unlink(reffile);
+ return;
+}
+
+/* rdtext - process a file */
+ rdtext(ifile)
+ FILE *ifile;
+{ char c, *p, rec[REFSIZE];
+ int i, toolong;
+ int sortdefs();
+
+ sortdefs();
+ biblineno = 1;
+ for (;;) {
+ while (getch(c, ifile) == '\n')
+ biblineno++; /* skip leading newlines */
+ if (c == EOF)
+ return;
+
+ toolong = false; /* flag to indicate reference is too long */
+ p = rec; /* read a reference */
+ for(*p++ = c; getch(c,ifile) != EOF; *p++ = c){
+ if (p-rec >= REFSIZE-1) {
+ toolong = true; /* reference entry is too long */
+ break;
+ }
+ if (c != '\n') continue; /* get next character */
+ if (getch(c, ifile) == '\n' || c == EOF) { /* end of ref */
+ biblineno++;
+ c = *p++ = '\n'; /* set c = \n to indicate normal exit */
+ break;
+ }
+ if (c == '.' || c == '%')
+ *p++ = '\n';
+ else
+ *p++ = ' ';
+ if (p-rec >= REFSIZE-1) {
+ toolong = true; /* reference entry is too long */
+ break;
+ }
+ }
+ if (c == EOF) error("ill formed reference file");
+ *p = 0;
+
+ if (toolong){ /* ref. entry too long */
+ biblineno++; /* biblineno was not inc due to break exit */
+ *(p-1) = '\n'; /* set end of field to \n for consistency */
+ for (; c != EOF; getch(c,ifile)){
+ if (c != '\n') continue; /* get next character */
+ if (getch(c, ifile) == '\n') break;
+ if (c == EOF){
+ c = '\n'; /* normal exit, file ends with \n */
+ break;
+ }
+ }
+ if (c == EOF) error("ill formed reference file");
+ if (silent == false){
+ fprintf(stderr,
+ "Truncated following input reference to REFSIZE-1 (%d) characters:\n"
+ ,REFSIZE-1);
+ fprintf(stderr,"-------------\n%s\n-------------\n",rec);
+ }
+ }
+
+ expnd2(rec);
+
+ if (numrefs++ > MAXLIST)
+ error("too many references");
+ refspos[numrefs] = rend;
+#ifdef READWRITE
+ fixrfd( WRITE ); /* fix access mode of rfd, if nec. */
+#else
+ fseek(rfd, rend, 0);
+#endif
+ i = strlen(rec) + 1;
+ fwrite(rec, 1, i, rfd);
+ rend = rend + i;
+ }
+}
diff --git a/biblio/tib/src/tiblook.c b/biblio/tib/src/tiblook.c
new file mode 100644
index 0000000000..6e2c5085e1
--- /dev/null
+++ b/biblio/tib/src/tiblook.c
@@ -0,0 +1,171 @@
+/* Tiblook -- looks up references */
+/* as supplied, tiblook uses unix routine getopt;
+ if unavailable, program can be modified by removing definition
+ of GETOPT ---
+ resulting program works in interactive mode only */
+
+#define GETOPT
+#include "stdio.h"
+#include "tib.h"
+
+char *locate();
+
+int max_klen = 6; /* max length of keys */
+char *common = /* name of file of common words */
+ COMFILE;
+char INDEXF[MAXSTR] = /* name of index file */
+ INDXFILE;
+char optch2[]=OPTCH; /* option character on call */
+
+int argc;
+char **argv;
+int noref = 0; /* reference found? */
+#ifdef GETOPT
+main(argc,argv)
+int argc;
+char **argv;
+{ char *refs;
+ char keys[MAXSTR];
+ char *p,*q, *pcom, *getenv();
+ char one_index[MAXSTR];
+ char *pindx, *getenv();
+
+ int getopt();
+ int opt;
+ extern char *optarg;
+ extern int optind;
+
+ while ((opt = getopt(argc, argv, "l:c:p:")) !=EOF)
+ { switch (opt)
+ { case 'l': max_klen= atoi(optarg);
+ break;
+ case 'c': common= optarg;
+ break;
+ case 'p': strcpy(INDEXF,optarg);
+ break;
+ case '?':
+ default: fprintf(stderr, "invalid switch '%c'\n", opt);
+ }
+ }
+#endif
+#ifndef GETOPT
+
+main(argcount,arglist)
+int argcount;
+char **arglist;
+{ char *refs;
+ char keys[MAXSTR];
+ char *p,*q, *pcom, *getenv();
+ char one_index[MAXSTR];
+ char *pindx, *getenv();
+
+ argc= argcount-1;
+ argv= arglist+1;
+ flags();
+#endif
+
+ /* add SYSINDEX to search path. all names are comma terminated */
+ strcat(INDEXF, ",");
+ pindx = getenv("SYSINDEX");
+ if (pindx == NULL)
+ strcat(INDEXF, SYSINDEX);
+ else
+ strcat(INDEXF, pindx);
+ strcat(INDEXF, ",");
+
+/* set common words file name */
+
+ pcom = getenv("COMFILE");
+ if (pcom != NULL)
+ strcpy (common,pcom);
+
+#ifdef GETOPT
+
+ if (optind != argc) {
+ for ( ; optind < argc; optind++) {
+ strcat(keys, argv[optind]);
+ strcat(keys, " ");
+ }
+ for (p = one_index, q = INDEXF; *q != NULL; q++)
+ if (*q == ',' )
+ { *p = 0;
+ refs = locate(keys, one_index, max_klen, common);
+ if( refs==NULL ) {
+ strcpy(q-strlen(one_index),q+1);
+ q = q-strlen(one_index)-1;
+ }
+/* if (refs!=NULL && *refs!=NULL) break;*/
+ if (refs!=NULL && *refs!=NULL) {
+ printf("%s", refs);
+ if (refs!=NULL) free(refs);
+ }
+ p = one_index;
+ }
+ else *p++ = *q;
+
+/* if (refs==NULL || *refs==NULL) printf("No references found.\n");
+ else printf("%s", refs);
+ if (refs!=NULL) free(refs);*/
+
+ exit(0);
+ }
+#endif
+
+ /* header */
+ fprintf (stderr, "Tiblook -- version %s, released %s.\n", VERSION, RDATE);
+
+ printf("Enter keys separated by spaces for search, <return> to exit ...\n\n*");
+
+ while (fgets(keys,MAXSTR,stdin)!=NULL)
+ { if (keys[0] == '\n') exit(0);
+ for (p = one_index, q = INDEXF; *q != 0 ; q++)
+ if (*q == ',' )
+ { *p = 0;
+ refs = locate(keys, one_index, max_klen, common);
+ if( refs==NULL )
+ { fprintf(stderr,
+ "%s removed from index list.\n", one_index);
+ /* delete this file name (shift remainder on top) */
+ strcpy(q-strlen(one_index),q+1);
+ q = q-strlen(one_index)-1;
+ }
+/* if (refs!=NULL && *refs!=NULL) break;*/
+ if (refs!=NULL && *refs!=NULL) {
+ printf("%s", refs);
+ if (refs!=NULL) free(refs);
+ noref=1;
+ }
+ p = one_index;
+ }
+ else *p++ = *q;
+
+/* if (refs==NULL || *refs==NULL) printf("No references found.\n");*/
+ if (noref == 0) printf("No references found.\n");
+/* else printf("%s", refs);
+ if (refs!=NULL) free(refs);*/
+ printf("*");
+ noref = 0;
+ }
+ exit(0);
+}
+
+ clnup()
+{
+ return;
+}
+
+#define operand (strlen(*argv+2)==0 ? (argv++,argc--,*argv) : *argv+2)
+
+flags()
+{ for (; argc>0 && *argv[0]==optch2[0]; argc--,argv++)
+ { switch ((*argv)[1])
+ { case 'l': max_klen= atoi(operand);
+ break;
+ case 'c': common= operand;
+ break;
+ case 'p': strcpy(INDEXF,operand);
+ break;
+ default: fprintf(stderr, "invalid switch '%s'\n", *argv);
+ }
+ }
+}