diff options
Diffstat (limited to 'biblio/tib/src')
-rw-r--r-- | biblio/tib/src/Makefile | 55 | ||||
-rw-r--r-- | biblio/tib/src/locate.c | 217 | ||||
-rw-r--r-- | biblio/tib/src/makekey.c | 74 | ||||
-rw-r--r-- | biblio/tib/src/seek.c | 73 | ||||
-rw-r--r-- | biblio/tib/src/streams.c | 136 | ||||
-rw-r--r-- | biblio/tib/src/tib.c | 775 | ||||
-rw-r--r-- | biblio/tib/src/tibargs.c | 1876 | ||||
-rw-r--r-- | biblio/tib/src/tibdex.c | 239 | ||||
-rw-r--r-- | biblio/tib/src/tiblist.c | 219 | ||||
-rw-r--r-- | biblio/tib/src/tiblook.c | 171 |
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); + } + } +} |