# to unbundle, sh this file (in an empty directory) echo README 1>&2 sed >README <<'//GO.SYSIN DD README' 's/^-//' - -bibsrch is a program to search a bib file for key words. The key -words are contained in a field called kwds. The program has the -ability to search on user specified conjunctions, disjunctions, and -negations of key words. An auxiliary program, getkey, spills out the -keywords in a bib file. For more details see bibsrch.doc. - -To create bibsrch in the directory created from bibsrch.tar, enter - - make - -To create getkey, enter - - make -f makekey //GO.SYSIN DD README echo andmatch.c 1>&2 sed >andmatch.c <<'//GO.SYSIN DD andmatch.c' 's/^-//' -/* - * andmatch determines whether all of the keywords - * in the string s match at least one keyword in the string - * t. Keywords are separated by commas in both strings. - * Blanks before and after the first and last nonblank - * character are trimmed. -*/ - -#include "bibsrch.h" - -andmatch(s, t) -char *s, *t; -{ - char u[50], v[50]; - int i1, i2, j1, j2, m, ok; - - m = TRUE; - - i1 = -1; - while (TRUE){ - - mvto(",", i1, &i2, s); - trim(s, i1+1, i2-1, u); - - ok = FALSE; - j1 = -1; - while(TRUE){ - - mvto(",", j1, &j2, t); - trim(t, j1+1, j2-1, v); - - if (u[0] == '!'){ - if (!strcmp(&u[1],v)) break; - if (ok = t[j2] == '\0') break; - } - else if (u[0] == '^'){ - if (ok = substr(&u[1], v)) break; - if (t[j2] == '\0') break; - } - else{ - if (ok = !strcmp(u, v)) break; - if (t[j2] == '\0') break; - } - j1 = j2; - } - - if (!(m = m && ok) || s[i2] == '\0') break; - i1 = i2; - } - return(m); -} //GO.SYSIN DD andmatch.c echo bibsrch.c 1>&2 sed >bibsrch.c <<'//GO.SYSIN DD bibsrch.c' 's/^-//' -/* - - Coded by G. W. Stewart (stewart@cs.umd.edu) February 28, 1991. - - bibsrch is a program to search a bib file for matches to - keywords. The keywords in the entries of the bib file are - contained in a field labeled kwds. The user can specify - keywords in disjuctive or conjunctive form with negations. The - user can also specify a string to match in the author field to - make searches by individual author possible. The standard - output can be used for browsing or the matched entries can be - sent to an output file, either in raw form or as \nocite - commands. For details on usage see bibsrch.doc - - CIMICES CAUTIONESQUE - - The character "@" cannot appear outside a bibtech entry - except to introduce an entry. - - bibsrch requires that all bibtex fields be quoted, even - those consisting entirely of numbers. - - The input file should not generate warnings when it is - run through bibtex. - - Key phrases in the input file must not be broken across - lines. - - bibsrch runs at less than blinding speed. On my SUN 3/160 it - requires about twenty seconds to search 1230 entries for a - keyword. A search for an author requires about twelve seconds - (it is to your advantage to specify an author if you can). - -*/ - -#include -#include "bibsrch.h" - -main(argc, argv) -int argc; -char *argv[]; -{ - int andmatch(), bibout, conj, entry(), field(), i, match, - nt, nl, ormatch(), output, query; - char author[100], buf[BSIZE], c, getfch(), infile[20], key[20], - s[BSIZE], term[MAXTERM][100]; - FILE *fopen(), *inp, *outp; - - if (argc == 1){ - printf("Usage: bibsrch infile [outfile]\n"); - exit(); - } - - /* Set up the input file. */ - - strcpy(infile, argv[1]); - - if (!(inp = fopen(strcat(infile, ".bib"), "r"))){ - printf("Can't open %s\n", infile); - exit(); - } - - query = TRUE; - output = FALSE; - - if (argc >= 3){ - - /* There is an output file. Ask about options. */ - - output = TRUE; - - if (!(outp = fopen(argv[2], "w"))){ - printf("Can't open %s\n", argv[2]); - exit(); - } - - printf("\nbibtech or raw output (*, r)? "); - if (getfch() == 'r') - bibout = FALSE; - else{ - - /* bibtex output. Set up the file. */ - - bibout = TRUE; - fprintf(outp, "\\documentstyle[11pt]{article}\n"); - fprintf(outp, "\\pagestyle{plain}\n"); - fprintf(outp, "\\begin{document}\n"); - fprintf(outp, "\\bibliographystyle{plain}\n"); - fprintf(outp, "\\bibliography{%s}\n", argv[1]); - } - } - - /* Loop until no more sessions */ - - loop: - - /* Set up the session */ - - if (output){ - printf("\nQueries (*, n)? "); - if (getfch() == 'n') - query = FALSE; - else - query = TRUE; - } - - printf("\nAuthor? "); - gets(author); - - printf("\nConjunctive or disjunctive form (*, d)? "); - if (getfch() == 'd') - conj = FALSE; - else - conj = TRUE; - - printf("\nEnter keywords\n\n"); - - nt = 0; - while (TRUE){ - gets(term[nt]); - if (*term[nt] == '\0') break; - if(++nt == MAXTERM){ - printf("No more space for terms. Abort the search? "); - if (getfch() == 'y') - exit(); - else - break; - } - - if (conj) - printf("and\n"); - else - printf("or\n"); - } - - /* Search through the input file for matches */ - - while (entry(inp, buf, BSIZE, key)){ - - if (!(*author == '\0')){ - if (!field("author", s, buf)) continue; - if (!substr(author, s)) continue; - } - - if (!field("kwds", s, buf)) continue; - - if (conj){ - match = TRUE; - for(i= 0; i&2 sed >bibsrch.doc <<'//GO.SYSIN DD bibsrch.doc' 's/^-//' - BIBSRCH - - G. W. Stewart - - -INTRODUCTION - -bibsrch is a program to search a BIBTEX bib file on a combination of -author and keywords. The keywords or phrases are contained in a -"kwds" field of each bibtex entry and are matched against keywords -and phrases given bibsrch by the user. The matched entries can be -directed to an output file, either in a form that can be run through -bibtech to produce a bibliography or in raw form to produce a new -reference base. - - -USAGE - -bibsrch in invoked by the statement - - bibsrch infile [outfile] - - infile -- the name of the .bib file to - be searched - - outfile -- the name of an optional output - file. Invoking bibsrch without - an output file allows one to - browse through the bibliography. - -bibsrch will respond with some queries which control the search and -the form of the output. - -bibtech or raw output (* or r)? - - r -- (any string beginning with "r") -- bibsrch will write the - actual bib file entries to the output file. - - * -- (anything else) -- bibsrch will create a latex file of - "\nocite" commands that will produce a bibliography when run - with latex and bibtex. - -Queries (* or n)? - - * -- print out the bibfile entry just matched and ask if it is to - be saved. - - n -- suppress the printing of queries. - - Queries cannot be suppressed if there is no output file. - -Author? - - The response is a string s. bibsrch will only match entries in - which s is a substring of the author field. A carriage return - suppresses the search by author. - -conjunctive or disjunctive form (* or d)? - - * -- The keywords for the search are divided into groups of terms. - A term consists of a list of keywords, keywords immediately - preceded by the symbol "!", and strings immediately preceded - by the symbol "^". The members of a list are separated by - commas. A keyword not proceeded by "!" matches an entry if - it is in the keyword list. A keyword preceded by "!" - matches if it is not in the keyword list. A string preceded - by "^" matches if it is a substring of a member of the - keyword list. A term matches if one of its keywords matches. - A group of terms matches if all the terms match. - - d -- Here a term matches only if all its keywords match. A group - of terms matches if at least one of its terms matches. - - Note that in a disjunction an empty group of terms never matches, - while an empty conjunction always matches. Thus to search by - author only, enter a carriage return in response to this query. - - The "^" option is particularly useful when you cannot remember the - exact form of a key word or phrase but are pretty sure of a - substring of it. For example "^Lanc" will get everything having - to do with Lanczos, be it the man himself or the "Lanczos - algorithm". - -Enter keywords - - Begin entering the terms of the keyword expression. A term - consists of keywords separated by commas, each optionally preceded - by a "~". Blanks before the first and after the last nonblank - character are trimmed. However, blanks within the keyword are - left as they are to permit key phrases. bibsrch distinguishes - between lower and upper case in keywords. bibsrch will continue - asking for terms (by querying "or" or "and", whichever is - appropriate) until an empty term (CR) is entered. - -Enter, skip, abort (*, s, a)? - - This query is printed out after each match. - - * -- place the entry in the output file. - - s -- skip to the next match, generating no output. - - - a -- abort the search (useful when it is obvious that things have - gone wrong). - - If there is no output file (browse mode), the enter and skip - options are combined into a continue option. - -Continue, quit (*, q)? - - This query is printed out after a session. If you choose to - continue, bibsrch picks up with the author query. The output - file, if any, remains the same. - -EXAMPLES - -The following session gets all references concerning eigenvalue and -generalized eigenvalue problems that do not have the keyword -symmetric--presumably the nonsymmetric problems. Note that the -abbreviations are particular to my reference base. - ----------------------------------------------------------------------- - -Author? - -Conjunctive or disjunctive form (*, d)? - -Enter keywords - -eig, geig -and -~symmetric -and - ----------------------------------------------------------------------- - -The following session gets all references about sparse eigenvalue -problems and the Lanczos algorithm written by Parlett. - ----------------------------------------------------------------------- -Author? Parlett - -Conjunctive or disjunctive form (*, d)? d - -Enter keywords - -Lanczos algorithm -or -eig, sparse -or - ----------------------------------------------------------------------- - -The following session picks up references having the keywords -"diagonal", "block diagonal", "diagonalization", -"block diagonalizaton", etc. - ----------------------------------------------------------------------- - -Author? - -Conjunctive or disjunctive form (*, d)? - -Enter Keywords - -^diagonal -and - ----------------------------------------------------------------------- - -The following session gets everything by J. E. Dennis. - ----------------------------------------------------------------------- - -Author? J. E. Dennis - -Conjunctive or disjunctive form (*, d)? - -Enter keywords - ----------------------------------------------------------------------- - -GETKEY - -getkey dumps keywords of a bib file onto the standard output. To get -an alphabetized list of all key words from the file ref.bib execute - - getkey ref | sort -uf > keywords - - - //GO.SYSIN DD bibsrch.doc echo bibsrch.h 1>&2 sed >bibsrch.h <<'//GO.SYSIN DD bibsrch.h' 's/^-//' -#define TRUE 1 -#define FALSE 0 -#define MAXTERM 5 -#define BSIZE 5000 //GO.SYSIN DD bibsrch.h echo entry.c 1>&2 sed >entry.c <<'//GO.SYSIN DD entry.c' 's/^-//' -/* - * entry locates the first next entry in the bib file - * "file". The entry is placed as a string in the buffer - * b of size bs. The key for the entry is returned in - * key. -*/ - -#include -#include "bibsrch.h" - -entry(file, b, bs, key) - -FILE *file; -char b[], key[]; -int bs; - -{ - int i1, i2, i3; - - if (!skpto(file, '@')) return(FALSE); - - b[0] = '@'; - if (!getto(file, "{(", 0, &i1, b, bs)) return(FALSE); - if (!getto(file, ",", i1, &i2, b, bs)) return(FALSE); - - if (!gettom(file, b[i1], i2, &i3, b, bs)) return(FALSE); - b[i3+1] = '\0'; - - trim(b, i1+1, i2-1, key); - return(TRUE); -} //GO.SYSIN DD entry.c echo field.c 1>&2 sed >field.c <<'//GO.SYSIN DD field.c' 's/^-//' -/* - * field takes a bib file entry contained in the - * string b and determines if it has a field with the - * name specified by the string name. -*/ - -#include "bibsrch.h" - -field(name ,field, b) - char name[], field[], b[]; -{ - int n1, n2, f1, f2, t; - char s[20]; - - f2 = -1; - while(TRUE){ - - if (!mvto(",", f2, &n1, b)) return(FALSE); - if (!mvto("=", n1, &n2, b)) return(FALSE); - - trim(b, n1+1, n2-1, s); - - if (!mvto("\"{", n2, &f1, b)) return(FALSE); - if (b[f1] == '"'){ - t = f1; - while (TRUE){ - if (!mvto("\"{", t, &t, b)) return(FALSE); - if (b[t] == '"') break; - if (!mvtom('{', t, &t, b)) return(FALSE); - } - f2 = t; - } - else - if (!mvtom('{', f1, &f2, b)) return(FALSE); - - if (!strcmp(s, name)){ - trim(b, f1+1, f2-1, field); - return(TRUE); - } - } -} //GO.SYSIN DD field.c echo getfch.c 1>&2 sed >getfch.c <<'//GO.SYSIN DD getfch.c' 's/^-//' -/* - * getfch gets the first character from the current line - * of the input stream and flushes the rest of the line. -*/ - -char getfch() -{ - char c, d; - - c = d = getchar(); - while(d != '\n') d = getchar(); - - return(c); -} //GO.SYSIN DD getfch.c echo getkey.c 1>&2 sed >getkey.c <<'//GO.SYSIN DD getkey.c' 's/^-//' -/* - getkey dumps the kewords and phrases from the kwds fields of - a bib file. Pipe the output to sort with the -u option to - get an alphebetized list. The number of entries in the bib - file is printed on stderr. -*/ - -#include -#include "bibsrch.h" - -main(argc, argv) -int argc; -char *argv[]; -{ - int andmatch(), bibout, conj, count, entry(), field(), i, i1, i2, match, - nt, nl, ormatch(), output, query; - char author[100], buf[BSIZE], c, getfch(), infile[20], key[20], - s[BSIZE], t[100], term[MAXTERM][100]; - FILE *fopen(), *inp; - - if (argc <= 1){ - fprintf(stderr, "Usage: getkey infile\n"); - exit(); - } - - strcpy(infile, argv[1]); - - if (!(inp = fopen(strcat(infile, ".bib"), "r"))){ - fprintf(stderr, "Can't open %s\n", infile); - exit(); - } - - count = 0; - - while (entry(inp, buf, BSIZE, key)){ - - count++; - if (!field("kwds", s, buf)) continue; - i1 = -1; - while(TRUE){ - mvto(",", i1, &i2, s); - trim(s, i1+1, i2-1, t); - printf("%s\n", t); - i1 = i2; - if (s[i2] == '\0') break; - } - } - - fprintf(stderr, "There were %d entries.\n", count); - exit(); -} //GO.SYSIN DD getkey.c echo getto.c 1>&2 sed >getto.c <<'//GO.SYSIN DD getto.c' 's/^-//' -#include -#include "bibsrch.h" - -/* - * getto moves to the first character in the input - * file that matches one of the characters in the - * string s. The string is placed in location i1+1 through - * i2 of the character buffer b of size bs. FALSE - * is returned on an end of file. Buffer overflow - * generates an error message. -*/ - -getto(file, s, i1, i2, b, bs) - -FILE *file; -char s[], b[]; -int i1, *i2, bs; -{ - int i, j, n; - - n = strlen(s); - *i2 = i1; - - while (++(*i2) < bs){ - - if((b[*i2] = getc(file)) == EOF) return(FALSE); - - for (j=0; j&2 sed >gettom.c <<'//GO.SYSIN DD gettom.c' 's/^-//' -#include -#include "bibsrch.h" - -/* - * gettom moves to the first deliminter matching c in the - * file that matches one of the characters in the - * string s. The string is placed in location i1+1 through - * i2 of the character buffer b of size bs. FALSE - * is returned on an end of file. Buffer overflow - * generates an error message. -*/ - -gettom(file, c, i1, i2, b, bs) - -FILE *file; -char c, b[]; -int i1, *i2, bs; -{ - int count; - char s[3]; - - count = 1; - - switch (c){ - case '{': - strcpy(s, "{}"); - break; - case '(': - strcpy(s, "()"); - } - - *i2 = i1; - while (count > 0){ - - if (!getto(file, s, *i2, i2, b, bs)) return(FALSE); - - if (b[*i2] == c) - count++; - else - count--; - } - return(TRUE); -} //GO.SYSIN DD gettom.c echo makefile 1>&2 sed >makefile <<'//GO.SYSIN DD makefile' 's/^-//' -BIBSRCH = bibsrch.o \ - andmatch.o \ - entry.o \ - field.o \ - getfch.o \ - getto.o \ - gettom.o \ - mvto.o \ - mvtom.o \ - ormatch.o \ - skpto.o \ - substr.o \ - trim.o - -bibsrch: $(BIBSRCH) - cc $(BIBSRCH) -o bibsrch - -$(BIBSRCH): bibsrch.h //GO.SYSIN DD makefile echo makekey 1>&2 sed >makekey <<'//GO.SYSIN DD makekey' 's/^-//' -GETKEY = getkey.o \ - andmatch.o \ - entry.o \ - field.o \ - getfch.o \ - getto.o \ - gettom.o \ - mvto.o \ - mvtom.o \ - ormatch.o \ - skpto.o \ - substr.o \ - trim.o - -getkey: $(GETKEY) - cc $(GETKEY) -o getkey - -$(GETKEY): bibsrch.h //GO.SYSIN DD makekey echo mvto.c 1>&2 sed >mvto.c <<'//GO.SYSIN DD mvto.c' 's/^-//' -#include "bibsrch.h" - -/* - * mvto finds the first character b[i2] following - * the caracter b[i1] that matches one of the character - * in the string s. It returns FALSE if there is no - * such character. -*/ - -mvto(s, i1, i2, b) - -char s[], b[]; -int i1, *i2; -{ - int i, j, n; - - n = strlen(s); - *i2 = i1; - - while (b[++(*i2)] != '\0'){ - - for (j=0; j&2 sed >mvtom.c <<'//GO.SYSIN DD mvtom.c' 's/^-//' -#include "bibsrch.h" - -/* - * mvtom findes the first character b[i2] following b[i1] - * in the string b that matches the delimiter c. Returns - * false if there is no such character. -*/ - -mvtom(c, i1, i2, b) - -char c, b[]; -int i1, *i2; -{ - int count; - char s[3]; - - count = 1; - - switch (c){ - case '{': - strcpy(s, "{}"); - break; - case '(': - strcpy(s, "()"); - } - - *i2 = i1; - while (count > 0){ - - if (!mvto(s, *i2, i2, b)) return(FALSE); - - if (b[*i2] == c) - count++; - else - count--; - } - return(TRUE); -} //GO.SYSIN DD mvtom.c echo ormatch.c 1>&2 sed >ormatch.c <<'//GO.SYSIN DD ormatch.c' 's/^-//' -/* - * ormatch determines whether one of the keywords - * in the string s matches at least one keyword in the string - * t. Keywords are separated by commas in both strings. - * Blanks before and after the first and last nonblank - * character are trimmed. -*/ - -#include "bibsrch.h" - -ormatch(s, t) -char *s, *t; -{ - char u[50], v[50]; - int i1, i2, j1, j2, m, ok; - - m = FALSE; - - i1 = -1; - while (TRUE){ - - mvto(",", i1, &i2, s); - trim(s, i1+1, i2-1, u); - - ok = FALSE; - j1 = -1; - while(TRUE){ - - mvto(",", j1, &j2, t); - trim(t, j1+1, j2-1, v); - - if (u[0] == '!'){ - if (!strcmp(&u[1],v)) break; - if (ok = t[j2] == '\0') break; - } - else if (u[0] == '^'){ - if (ok = substr(&u[1], v)) break; - if (t[j2] == '\0') break; - } - else{ - if (ok = !strcmp(u, v)) break; - if (t[j2] == '\0') break; - } - j1 = j2; - } - - if ((m = m || ok) || s[i2] == '\0') break; - i1 = i2; - } - return(m); -} //GO.SYSIN DD ormatch.c echo skpto.c 1>&2 sed >skpto.c <<'//GO.SYSIN DD skpto.c' 's/^-//' -#include -#include "bibsrch.h" - -/* - * skipto sckips to the first occurence of the - * character c in the file stream file. Ruturns false - * on end of file. -*/ - -skpto(file, c) - -FILE *file; -char c; -{ - char d; - - while(TRUE){ - if ((d = getc(file)) == EOF) return(FALSE); - if (d == c) return(TRUE); - } -} //GO.SYSIN DD skpto.c echo substr.c 1>&2 sed >substr.c <<'//GO.SYSIN DD substr.c' 's/^-//' -#include "bibsrch.h" - -/* substr returns TRUE is s is a substring of t, - * otherwise FALSE. -*/ - -substr(s, t) -char *s, *t; -{ - char *ss, *tt; - int m; - - if(*s == '\0') return(TRUE); - - for (; *t!='\0'; t++){ - - ss = s; tt = t; m = TRUE; - while (TRUE){ - if (*ss++ != *tt++) break; - if (*ss == '\0') return(TRUE); - if (*tt == '\0') return(FALSE); - } - } - return(FALSE); -} //GO.SYSIN DD substr.c echo trim.c 1>&2 sed >trim.c <<'//GO.SYSIN DD trim.c' 's/^-//' -/* - * trim trims off leading and trailing blanks and newlines - * from the portion of the string b lying between n1 and n2. - * The resulting string is returned in s. -*/ - -trim(b, n1, n2, s) - -char b[], s[]; -int n1, n2; -{ - while (b[n1]==' ' || b[n1]=='\n') n1++; - while (b[n2]==' ' || b[n2]=='\n') n2--; - - while (n1 <= n2) *s++ = b[n1++]; - *s = '\0'; -} //GO.SYSIN DD trim.c