From decwrl!purdue!mailrus!uunet!allbery Tue Dec 5 07:52:41 PST 1989 Article 1212 of comp.sources.misc: Path: decwrl!purdue!mailrus!uunet!allbery From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) Newsgroups: comp.sources.misc Subject: v09i046: bibtools: tools for BibTeX Message-ID: <73343@uunet.UU.NET> Date: 5 Dec 89 03:13:43 GMT Sender: allbery@uunet.UU.NET Reply-To: Lines: 7226 Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) Posting-number: Volume 9, Issue 46 Submitted-by: kannan@osc.edu (Kannan Varadhan) Archive-name: bibtools I have written out what I think are fairly decent and comprehensive set of tools for manipulating BibTeX style bibliographies that I would like to have distributed via 'comp.sources.misc'. With this intent in mind, I am sending you this shar file. Briefly, the tools that I have are... bibc - This is a tool for creating and appending bibliography records to a file. This program works by prompting the user for the required fields, and then writes out/appends the record in the correct format. bibv - This tool takes one or more bib files, and produces a sample file, called bibtex.tex, and a dvi version of the same, that contain an entry corresponding to every record in the files. This uses bibtex to flag duplicate entries, hence, the name BIB-Verifier. shbib - This is used to show complete entries matching a given regular expression. The syntax is somewhat similar to egrep. rmbib - This removes entries matching the given regular expression from the specified files. It is useful, in that, the delete records are written to stdout, so one can shuffle records around various bib-files. You will also find, a library of tools that I designed, for breaking up entries in set of specified bibliography files, and having each entry processed by a routine of the user's choice. Notes on these can be found in README.lib_bib. The manpages have more detailed information. Installation requires one to have Henry Spencer's regular expression package, and Flex. #-------------------------------------------------------------------------- # to unpack the routine(s) in this package, remove everything # above the dotted line and say, `sh filename' # If any of the routines already exists, say, `sh -o filename' # Makefile README README.lib_bib TODO alpha.lex bibc.c bibc.h bibcent.c # bibcent.h bibl.l bibtools.man bibv.c bibv.h config.h foo.bib # gen_lex_file header includes.h inits.c lex.yy.c lexstrings.lex # lib_bib.c misc/ omega.lex pyr.regexp.a specl.bst strings.h sun.regexp.a # templates.c typescript misc/Changes misc/README misc/bibv.sh # misc/gets.c if [ ! -d . ] ; then echo -n Directory . not found. Creating.... mkdir . if [ ! -d . ] ; then echo ...failed echo unable to create directory .. Please create the directory and try again exit fi echo ...done fi echo -n "Makefile..." 1>&2 if test -f Makefile then case $# in 0) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac case $1 in -o) ;; *) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac fi sed 's/^X//' << 'EOFile Makefile' > Makefile X.SUFFIXES: .out .o .c .l .lex X X# The ARCH defines the type of architecture we are using to install X# these tools. This is essentially only to figure out the final BINDEST X# INCDIR defines the location of the regexp includes. X# RELIB defines the location of the regular expression library X# MANTYPE defines the location of the man pages, as manl/bibtools.l X# TEXLIB is the location to put specl.bst, the bibtex macro file XARCH=pyr XCFLAGS=-O XINCDIR=-I../Regexp XRELIB=$(ARCH).regexp.a XBINDEST=/n/shell/0/kannan/bin/${ARCH}/ XMANTYPE=l XMANDEST=/n/shell/0/kannan/man/man$(MANTYPE) XTEXLIB=/n/shell/0/kannan/Bib/ X XCCFLAGS=${CFLAGS} ${INCDIR} XINCLUDES=includes.h config.h strings.h X Xall: bibc shbib rmbib bibv X @echo Fee Fi Fo Fum X Xbibc: bibc.o lex.yy.o inits.o templates.o lib_bib.o X cc ${CFLAGS} bibc.o lex.yy.o inits.o templates.o lib_bib.o $(RELIB) -o $@ X Xshbib: shbib.o lib_bib.o X cc ${CFLAGS} shbib.o lib_bib.o $(RELIB) -o $@ X Xrmbib: rmbib.o lib_bib.o X cc ${CFLAGS} rmbib.o lib_bib.o $(RELIB) -o $@ X Xbibv: bibv.o lib_bib.o X cc ${CFLAGS} bibv.o lib_bib.o $(RELIB) -o $@ X Xbibc.o: bibc.c $(INCLUDES) bibc.h X cc -c ${CCFLAGS} bibc.c X Xinits.o: inits.c $(INCLUDES) bibc.h X cc -c ${CCFLAGS} inits.c X Xtemplates.o: templates.c $(INCLUDES) bibc.h X cc -c ${CCFLAGS} templates.c X Xlex.yy.o: lex.yy.c $(INCLUDES) X cc -c ${CCFLAGS} lex.yy.c X Xlex.yy.c: bibl.l $(INCLUDES) X flex -I bibl.l X Xbibl.l: alpha.lex lexstrings.lex omega.lex X gen_lex_file alpha.lex lexstrings.lex omega.lex > bibl.l X Xshbib.o: bibcent.c $(INCLUDES) bibcent.h X cc -c -DSHBIB ${CCFLAGS} bibcent.c X mv bibcent.o shbib.o X Xrmbib.o: bibcent.c $(INCLUDES) bibcent.h X cc -c -DRMBIB ${CCFLAGS} bibcent.c X mv bibcent.o rmbib.o X Xbibv.o: bibv.c $(INCLUDES) bibv.h X cc -c ${CCFLAGS} bibv.c X Xlib_bib.o: lib_bib.c $(INCLUDES) X cc -c ${CCFLAGS} lib_bib.c X Xinstall: all X install -s bibc ${BINDEST} X install -s bibv ${BINDEST} X install -s shbib ${BINDEST} X install -s rmbib ${BINDEST} X install -c specl.bst ${TEXLIB} X cp bibtools.man ${MANDEST}/bibtools.$(MANTYPE) X ln ${MANDEST}/bibtools.$(MANTYPE) ${MANDEST}/bibc.$(MANTYPE) X ln ${MANDEST}/bibtools.$(MANTYPE) ${MANDEST}/bibv.$(MANTYPE) X ln ${MANDEST}/bibtools.$(MANTYPE) ${MANDEST}/shbib.$(MANTYPE) X ln ${MANDEST}/bibtools.$(MANTYPE) ${MANDEST}/rmbib.$(MANTYPE) X Xclean: X rm -f bibc bibv shbib rmbib core linterrs *.o X Xlint: X lint $(INCDIR) bibc.c inits.c templates.c lib_bib.c lex.yy.c > linterrs X lint $(INCDIR) -DSHBIB bibcent.c lib_bib.c >> linterrs X lint $(INCDIR) -DRMBIB bibcent.c lib_bib.c >> linterrs X lint $(INCDIR) bibv.c lib_bib.c >> linterrs X X# X# Debug and test makes..... X# Xdebug: X make CFLAGS='-gx -DEBUG' ARCH=${ARCH} all X Xbackup: X @rm -f core linterrs *.o X (cd .. ; pack Bibcreate/* > bibc.shar) X Xmakes: X sed 's/^ARCH=.*/ARCH=sun/' Makefile > makefile.sun X sed 's/^ARCH=.*/ARCH=pyr/' Makefile > makefile.pyr EOFile Makefile chmod u=rw+,g=rw+,o=r++ Makefile echo '...done' 1>&2 if [ ! -d . ] ; then echo -n Directory . not found. Creating.... mkdir . if [ ! -d . ] ; then echo ...failed echo unable to create directory .. Please create the directory and try again exit fi echo ...done fi echo -n "README..." 1>&2 if test -f README then case $# in 0) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac case $1 in -o) ;; *) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac fi sed 's/^X//' << 'EOFile README' > README XCopyright (c) 1989 Ohio State University XWritten by Kannan Varadhan. Not derived from licensed software. X XPermission is granted to anyone to use this software for any purpose on Xany computer system, and to redistribute it freely, subject to the Xfollowing restrictions... X X 1. The author is not responsible for the consequences of use of X this software, no matter how awful, even if they arise X from defects in it. X X 2. The origin of this software must not be misrepresented, either X by explicit claim or by omission. X X 3. Altered versions must be plainly marked as such, and must not X be misrepresented as being the original software. X XInstalling bibc: X XBefore you start, you will need Xa) a regular expression package. I prefer to use the one that Henry XSpenser wrote aeons ago. This one is in the public domain. A copy of Xit should be in the Regexp directory. From this, we need regcomp(), Xregexec() and regerror(). X XIf you wish to use some other regular expression package, you have to Xfigure out how your set of routines will compile the re, and then how it Xwill execute a string on the resulting automaton. You can then change Xthe defines REGCOMP, REGEXEC, which are routine invokes, and REGEXP, the Xstruct, and change the includes for regexp.h in 'includes.h'. Simple, Xisn't it? :-) X Xb) You will also need flex before you can make bibc though. In case Xyou do not have access to flex, you could use the lex.yy.c with this Xcode, which has been generated with flex. X XBoth these packages have appeared on comp.sources.xxxxxxxx. X XNow edit Makefile, and config.h, and put in your various options. There Xare adequate comments alongside the various parameters, so one should Xhave no problem here. X XIf you are on a system V machine, edit strings.h, and make sure all the Xdefinitions there are ok too. X Xmake, and make install should see you through. X XNote that bibv uses a specially hacked bst file, called specl.bst. This Xstyle causes the bibitem keys to be the same as the \cite-keys that you Xhave used. This is a convenient style for keeping hardcopies for ready Xreference, considering that these are sorted nicely and all that :) XIf you would like to have a copy of the btxbst.doc file, send me a note, Xand I'll send it to you.... X XKANNAN Sun Dec 3 02:08:19 EST 1989 EOFile README chmod u=rw+,g=rw+,o=r++ README echo '...done' 1>&2 if [ ! -d . ] ; then echo -n Directory . not found. Creating.... mkdir . if [ ! -d . ] ; then echo ...failed echo unable to create directory .. Please create the directory and try again exit fi echo ...done fi echo -n "README.lib_bib..." 1>&2 if test -f README.lib_bib then case $# in 0) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac case $1 in -o) ;; *) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac fi sed 's/^X//' << 'EOFile README.lib_bib' > README.lib_bib XThis is a detailed note on the kind of functions available as part of a Xlibrary for manipulating bib-files. Hopefully, someone might find Xthis useful to write other tools to manipulate bibliographies in other Xways. X X------------------------------------------------------------------------- X Xchar * Xmy_gets (buffer, size) X/* X * This is an emulation of gets() using fgets.3 X * This routine reads everything upto a newline, using fgets.3 X * X * OUTPUT: Returns buffer on exit, (char *) NULL on error X * The contents of buffer are the input string, a max of (size -1) X * characters are filled on exit, X * The buffer is zeroed and returned on EOF. X * X * This routine only deals with EOF as an error cleanly. On any other X * error returned by fgets.3, this routine will return will return X * (char *) NULL and a partially filled buffer....*sigh* X * X * if EMUL_GETS is turned on, (it probably should, neh? :-) then X * it converts any trailing NEWLINE character ('\n') to a NIL ('\0') X * character, else, it leaves them alone X */ Xchar *buffer; Xint size; X X------------------------------------------------------------------------- X Xanswer (string, resp) X/* X * Display string, query user....return TRUE if answer = resp X */ Xchar *string; Xchar resp; X X------------------------------------------------------------------------- X Xprocess_bibfiles (files, process_recd, onerror) X/* X * For each file in files, X * delineate_next_record X * process_record (file, record); X * if process_record() indicates error, X * onerror (open_file_descriptor); X * lseek to EOF X * cause exit() X * X * An argument of "-" as a filename, returns the filedescriptor 0, X * corresponding to stdin. X */ Xchar **files; Xint (*process_recd)(), (*onerror)(); X X------------------------------------------------------------------------- X Xget_next_file (curfd) X/* X * Close current file descriptor; X * get next bib file from bibflist X * open file, and return new file descriptor; X * X * An argument of "-" as a filename, returns the filedescriptor 0, X * corresponding to stdin. X */ Xint curfd; X X------------------------------------------------------------------------- X Xchar * Xlcase (string) X/* X * Lower case the given string X */ Xchar *string; X X------------------------------------------------------------------------- X Xchar * Xreplstr (str) X/* X * replicate the given string. get storage, and return the new string. X */ Xchar *str; X X------------------------------------------------------------------------- X Xchar * Xdelineate_recd (string) X/* X * Get next record, using '\n@' as a flag per record. X * Match all braces, X * If record found, delineate current record by placing '\0' at end of X * current record, and return address of next record. X * else return (char *) NULL; X */ Xchar *string; X X------------------------------------------------------------------------- X Xstrcount (str, c) X/* X * Count the number of occurences of character 'c' in string "str" X */ Xchar *str; Xchar c; X X------------------------------------------------------------------------- X Xchar * Xget_atsign (str) X/* X * Get an atsign, check if it is preceeded by a newline X * If yes, return value, X * else repeat search X */ Xchar *str; X X------------------------------------------------------------------------- X XREGEXP * Xmy_rcomp (re) X/* X * STRATEGY: lcase the string inplace, and feed to regcomp(), return the X * value returned as is... X */ Xchar *re; X X{ return regcomp (lcase (re)); } X X------------------------------------------------------------------------- X Xmy_rexec (prog, str) Xregexp *prog; X/* X * my_rexec = TRUE, if lcase (copy of str) contains given re X * = FALSE otherwise. X */ Xchar *str; X EOFile README.lib_bib chmod u=rw+,g=r++,o=r++ README.lib_bib echo '...done' 1>&2 if [ ! -d . ] ; then echo -n Directory . not found. Creating.... mkdir . if [ ! -d . ] ; then echo ...failed echo unable to create directory .. Please create the directory and try again exit fi echo ...done fi echo -n "TODO..." 1>&2 if test -f TODO then case $# in 0) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac case $1 in -o) ;; *) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac fi sed 's/^X//' << 'EOFile TODO' > TODO Xerror handling in abrupt departures bibc X handled some of it...clean exit is still guaranteed, though X some garbage (?) gets seen on the screen Xsignals all X nyeah..considering the algorithm we are using for processing the X files, this, unless I am shown otherwise, is not going to be X really necessary! Consider the algorithms in brief: X X bibc: X while ! EOF do X get a record from user, X write out record, X done X bibv: For each file do X for each record in file do X get cite key X write into bibtex.tex X store filename X done X done X write out list of files, X run latex, bibtex, latex, latex X X shbib, rmbib: for each file do X for each record in file do X match regexp against record X if match, printout X if no match, and remove specified, X write record into file.bak X done X if file.bak exists rename file.bak as file X done X X Notice that the original file is never destroyed irrecoverably. Xcleaner handling of stdin shbib and rmbib X Question is, why? stdin can always be specified as "-" X to shbib, rmbib and bibv. With shbib and rmbib, a file "-.bak" X will be created for stdin, which is "safe". Xstat the file before editing bibc X DONE Xmanual pages all X Whatever, I guess XA README writeup on installation all X DONE XA writeup and comments for lib_bib.c libbib X DONE EOFile TODO chmod u=rw+,g=r++,o=r++ TODO echo '...done' 1>&2 if [ ! -d . ] ; then echo -n Directory . not found. Creating.... mkdir . if [ ! -d . ] ; then echo ...failed echo unable to create directory .. Please create the directory and try again exit fi echo ...done fi echo -n "alpha.lex..." 1>&2 if test -f alpha.lex then case $# in 0) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac case $1 in -o) ;; *) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac fi sed 's/^X//' << 'EOFile alpha.lex' > alpha.lex X%{ X X/* X * This program has been written by Kannan Varadhan. You are welcome to X * use, copy, modify, or circulate as you please, provided you do not X * charge any fee for any of it, and you do not remove these header X * comments from any of these files. X * X * -- kva Mon Dec 4 11:26:37 EST 1989 X */ X X#include "bibc.h" X#undef YY_INPUT X#define YY_INPUT(buf,reslt,msize) my_input (buf, &reslt, msize) X Xmy_input (buf,reslt, size) Xchar *buf; Xint *reslt; Xint size; X X{ Xchar inputln[80]; X X bzero (inputln, 80); X if (! GETS (inputln, 80)) X Strcpy (buf, "EOF"); X else X Strncpy (buf, inputln, size); X Strcat (buf, "!"); X#ifdef FLEX_DEBUG X Fprintf (stderr, "buf contains: %s\n", buf); X#endif X return *reslt = strlen (buf); X} X X Xmy_yylex () X X{ X#define PROMPTSTR "\ XWhat kind of record would you like to enter (one of the following)?\n\ X article book booklet conference\n\ X inbook incollection inproceedings manual\n\ X mastersthesis msthesis misc phdthesis\n\ X proceedings techreport unpublished\n\ Xor EDIT quit\n" X X Fprintf (stderr, PROMPTSTR); X return yylex (); X} X X%} EOFile alpha.lex chmod u=rw+,g=r++,o=r++ alpha.lex echo '...done' 1>&2 if [ ! -d . ] ; then echo -n Directory . not found. Creating.... mkdir . if [ ! -d . ] ; then echo ...failed echo unable to create directory .. Please create the directory and try again exit fi echo ...done fi echo -n "bibc.c..." 1>&2 if test -f bibc.c then case $# in 0) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac case $1 in -o) ;; *) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac fi sed 's/^X//' << 'EOFile bibc.c' > bibc.c X/* X * This program has been written by Kannan Varadhan. You are welcome to X * use, copy, modify, or circulate as you please, provided you do not X * charge any fee for any of it, and you do not remove these header X * comments from any of these files. X * X * -- kva Mon Dec 4 11:26:37 EST 1989 X */ X X#define GLOBALS X#include "bibc.h" X Xmain (argc, argv, envp) Xint argc; Xchar **argv, **envp; X X{ Xint retval; X X retval = FLD_NULL; X X (void) process_args (argc, argv); X (void) initialise (&bibitem); X X while (retval = my_yylex()) { X switch (retval) { X case FLD_ERROR: Fprintf (stderr, "Uh oh! no no no\n"); X continue; X case ARTICLE: retval = get_article (); break; X case BOOK: retval = get_book (); break; X case BOOKLET: retval = get_booklet (); break; X case CONFERENCE: retval = get_inproceedings (); break; X case INBOOK: retval = get_inbook (); break; X case INCOLLECTION: retval = get_incollection (); break; X case INPROCEEDINGS: retval = get_inproceedings (); break; X case MANUAL: retval = get_manual (); break; X case MASTERSTHESIS: retval = get_mastersthesis (); break; X case MISC: retval = get_misc (); break; X case PHDTHESIS: retval = get_phdthesis (); break; X case PROCEEDINGS: retval = get_proceedings (); break; X case TECHREPORT: retval = get_techreport (); break; X case UNPUBLISHED: retval = get_unpublished (); break; X case FLD_EDITOR: retval = edit (outfile, _O_outfilename, envp); break; X } X if (retval != -1) X (void) writeout (&bibitem, outfile); X (void) resetall (&bibitem); X } X fclose (outfile); X return 0; X} X Xwriteout (bi, outfile) Xbibrec *bi; XFILE *outfile; X X{ X#define PUT(VAR,REC) \ X if (ISSET (VAR,REC)) \ X { \ X if (Index (ISVAL(VAR,REC), QUOTE_CHAR)) \ X { tmp1 = OPEN_BRACE; tmp2 = CLOSE_BRACE ; } \ X else if (ISVAL(VAR,REC)[0] == '\\') \ X { \ X tmp1 = tmp2 = ' '; \ X ISVAL(VAR,REC)[0] = ' '; \ X } \ X else \ X tmp1 = tmp2 = QUOTE_CHAR; \ X Sprintf (recordbuf, "%s ,\n\t%s = %c%s%c", recordbuf, \ X (VAR)->REC.prompt, tmp1, ISVAL (VAR,REC), tmp2);\ X } Xchar recordbuf[1024]; Xchar tmp1, tmp2; Xint i; X X Sprintf (recordbuf, "@%s { %s", ISVAL(bi, rectype), ISVAL (bi, citekey)); X PUT (bi, address); X PUT (bi, annote); X PUT (bi, author); X PUT (bi, booktitle); X PUT (bi, chapter); X PUT (bi, edition); X PUT (bi, editor); X PUT (bi, howpublished); X PUT (bi, institution); X PUT (bi, journal); X PUT (bi, key); X PUT (bi, month); X PUT (bi, note); X PUT (bi, number); X PUT (bi, organisation); X PUT (bi, pages); X PUT (bi, publisher); X PUT (bi, school); X PUT (bi, series); X PUT (bi, title); X PUT (bi, type); X PUT (bi, volume); X PUT (bi, year); X PUT (bi, comment); X for (i = 0; i != usr_defns_ctr; i++) X PUT (bi, usr_defns[i]); X Strcat (recordbuf, "\n\t}\n\n"); X X (void) write (2, " ", 1); X if (_O_verbose) X Fprintf (stderr, recordbuf); X if (_O_verify) X { X if (answer ("Is this correct?", NO)) X return 0; X } X Fprintf (outfile, recordbuf); X fflush (outfile); X return 0; X} X X Xget_field (next_field, rectype, status) Xfield *next_field; Xchar *rectype; Xchar status; X X{ X#define ERRORMSG1 \ X "ERROR: %s is a REQUIRED FIELD for %s. Let's try that again...sigh...\n" X#define ERRORMSG2 \ X "ERROR: Frankly my dear, I don't give a damn...\n" Xchar inputline[512]; Xchar error; Xchar secondtime = FALSE; X XRETRY: Fprintf (stderr, "%s%s? ", next_field->prompt, X ((status == OPTIONAL)? " (optional)" : "" )); X fflush (stderr); X error = FALSE; X bzero (inputline, 512); X if (! GETS (inputline, 512)) X return -1; X switch (inputline[0]) { X case '\0': X if ((status == REQUIRED) && _O_pester_usr) X error = TRUE; X else X return 0; X break; X case '?': X Fprintf (stderr, "%s\n", next_field->helpstring); X goto RETRY; X case 'x': X if (! Strcmp(inputline, "xx")) X { X if (answer ("Abort?", YES)) X return -1; X } X case ' ': X (void) clr_leading_blanks (inputline); X if (Strlen(inputline) == 0) X { X if ((status == REQUIRED) && _O_pester_usr) X error = TRUE; X else X return 0; X } X break; X } X if (error) X { X if (secondtime) X { X Fprintf (stderr, ERRORMSG2, next_field->prompt, rectype); X return 0; X } X else X { X Fprintf (stderr, ERRORMSG1, next_field->prompt, rectype); X secondtime = TRUE; X goto RETRY; X } X } X Strcpy (next_field->string, inputline); X next_field->full = TRUE; X return 0; X} X X Xedit (filep, editfile, envp) XFILE *filep; Xchar *editfile; Xchar **envp; X X{ XFILE *freopen(); Xchar *EDITOR, *TEXEDIT, *getenv(); Xchar *string, *format_cmd(); Xint editorpid; Xint statresult; Xstruct stat efile; X X statresult = stat (editfile, &efile); X if ((statresult == -1) || (efile.st_mode & S_IFREG != 1)) X { X Fprintf (stderr, "Cannot edit file %s\n", editfile); X return -1; X } X TEXEDIT = getenv ("TEXEDIT"); X if (! TEXEDIT) X { X EDITOR = getenv ("VISUAL"); X if (! EDITOR) EDITOR = getenv ("EDITOR"); X if (! EDITOR) EDITOR = DEFAULT_EDITOR; X } X else X string = format_cmd (TEXEDIT, editfile); X X fclose (filep); X editorpid = fork(); X if (editorpid < 0) X { X perror ("Cannot fork Editor"); X exit (-2); X } X else if (editorpid == 0) /* CHILD */ X { X if (TEXEDIT) X execle ("/bin/sh", "sh", "-c", string, (char *) NULL, envp); X else X execlp (EDITOR, EDITOR, editfile, (char *) NULL, envp); X perror ("Cannot exec EDITOR, using DEFAULT_EDITOR"); X execlp (DEFAULT_EDITOR, DEFAULT_EDITOR, editfile, (char *) NULL, envp); X perror ("Cannot exec DEFAULT_EDITOR, giving up"); X exit (-3); X } X else X (void) wait ((union wait *) 0); X filep = freopen (_O_outfilename, "a", filep); X return -1 /* A wierd return code, indicating, print nothing..*/; X} X X Xclr_leading_blanks (string) Xchar *string; X X{ Xchar *temp, buffer[512]; X X temp = string; X while (*temp == ' ') temp++; X Strcpy (buffer, temp); X Strcpy (string, buffer); X return 0; X} X X X Xchar * Xformat_cmd (envstr, filename) Xchar *envstr, *filename; X X{ X/* X * The envstr is going to be the TEXEDIT environment string. X * The filename is going to be the name of the bibfile we are concerned with X * We assume that the format of the TEXEDIT string is going to be of the form X * [%d] %s X * The %d would be optional, and contain the displacement variable.... X * Since we are appending to the end of the bibfile always, we would X * position the editor to the bottom of the file always. X * Strategy...... X * locate the first %, if the character spec after it is not d, X * ie, it is not %d, then assume it is %s %d X * The %d is really unimportant then, see... X * stuff the stuff in, and return the cmd string... X */ Xint lineno; XFILE *temp, *fopen(); Xchar *strndx, buffer[100], cmdstr[100]; X X /* First find the size in terms of lines of filename */ X temp = fopen (filename, "r"); lineno = 0; X if (temp) X { X while (fgets (buffer, 100, temp)) lineno++; X fclose (temp); X lineno -= 10; /* An arbitrary figure */ X } X X /* lineno = %d specs now... */ X strndx = Index (envstr, '%'); X if (! strndx) X Strcpy (cmdstr, envstr); X else if (*++strndx == 'd') X Sprintf (cmdstr, envstr, lineno, filename); X else X Sprintf (cmdstr, envstr, filename, lineno); X return cmdstr; X} X EOFile bibc.c chmod u=rw+,g=r++,o=r++ bibc.c echo '...done' 1>&2 if [ ! -d . ] ; then echo -n Directory . not found. Creating.... mkdir . if [ ! -d . ] ; then echo ...failed echo unable to create directory .. Please create the directory and try again exit fi echo ...done fi echo -n "bibc.h..." 1>&2 if test -f bibc.h then case $# in 0) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac case $1 in -o) ;; *) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac fi sed 's/^X//' << 'EOFile bibc.h' > bibc.h X/* X * This program has been written by Kannan Varadhan. You are welcome to X * use, copy, modify, or circulate as you please, provided you do not X * charge any fee for any of it, and you do not remove these header X * comments from any of these files. X * X * -- kva Mon Dec 4 11:26:37 EST 1989 X */ X X#include "includes.h" X X#define OPTIONAL FALSE X#define REQUIRED TRUE X X#define FLD_ERROR -1 X#define FLD_NULL 0x0000 X#define ARTICLE 0x0001 X#define BOOK 0x0002 X#define BOOKLET 0x0004 X#define CONFERENCE 0x0008 X#define INBOOK 0x0010 X#define INCOLLECTION 0x0020 X#define INPROCEEDINGS 0x0040 X#define MANUAL 0x0080 X#define MASTERSTHESIS 0x0100 X#define MISC 0x0200 X#define PHDTHESIS 0x0400 X#define PROCEEDINGS 0x0800 X#define TECHREPORT 0x1000 X#define UNPUBLISHED 0x2000 X#define FLD_EDITOR 0x4000 X X#define GET(VAR,FIELD,STATUS) \ X if (get_field (&(VAR)->FIELD, ISVAL(VAR, rectype), STATUS) == -1)\ X return -1 X#define SET(VAR,FIELD,VALUE) { \ X Strcpy ((VAR)->FIELD.string, VALUE); \ X (VAR)->FIELD.full = TRUE; \ X } X#define RESET(VAR,FIELD) { \ X Strcpy ((VAR)->FIELD.string, ""); \ X (VAR)->FIELD.full = FALSE; \ X } X#define ISSET(VAR,FIELD) (VAR)->FIELD.full X#define ISVAL(VAR,FIELD) (VAR)->FIELD.string X#define ISHELP(VAR,FIELD) (VAR)->FIELD.helpstring Xtypedef struct record { X char full /* Actually holds a boolean place value */; X char string[391] /* An even 32 words / field */; X char prompt[32]; X char helpstring[344] /* Display if user is confused */; X } field; X Xtypedef struct biblio_record { X field rectype; X field citekey; X field address; X field annote; X field author; X field booktitle; X field chapter; X field edition; X field editor; X field howpublished; X field institution; X field journal; X field key; X field month; X field note; X field number; X field organisation; X field pages; X field publisher; X field school; X field series; X field title; X field type; X field volume; X field year; X field comment; X field cross_ref; X field usr_defns[USR_DEFNS_MAX]; X } bibrec; X XDCL (char, _O_help, FALSE); XDCL (char, _O_verify, FALSE); XDCL (char, _O_verbose, TRUE); XDCL (FILE, *outfile, stdout); XDCL (char, _O_outfilename[50], ""); XDCL (char, _O_pester_usr, SAFE); X XDCLX (bibrec, bibitem); XDCL (int, usr_defns_ctr, 0); X X EOFile bibc.h chmod u=rw+,g=r++,o=r++ bibc.h echo '...done' 1>&2 if [ ! -d . ] ; then echo -n Directory . not found. Creating.... mkdir . if [ ! -d . ] ; then echo ...failed echo unable to create directory .. Please create the directory and try again exit fi echo ...done fi echo -n "bibcent.c..." 1>&2 if test -f bibcent.c then case $# in 0) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac case $1 in -o) ;; *) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac fi sed 's/^X//' << 'EOFile bibcent.c' > bibcent.c X/* X * This program has been written by Kannan Varadhan. You are welcome to X * use, copy, modify, or circulate as you please, provided you do not X * charge any fee for any of it, and you do not remove these header X * comments from any of these files. X * X * -- kva Mon Dec 4 11:26:37 EST 1989 X */ X X#define GLOBALS X#include "bibcent.h" X X#ifdef SHBIB X#undef RMBIB /* why? God alone knows */ X#endif X X#ifdef RMBIB X#define PROGSTR "rmbib" X#else X#define PROGSTR "shbib" X#endif X Xmain (argc, argv) Xint argc; Xchar *argv[]; X X{ Xextern int process_record(), onerror_cleanup(); X X if (process_args (argc, argv) == -1) X return -1 /* EXIT */; X regprog = (REGEXP *) REGCOMP (_O_regexp); X X (void) process_bibfiles (_O_flist, process_record, onerror_cleanup); X X (void) finish_up (); X return 0; X} X X Xfinish_up () X X{ X if (store.isfull) X (void) output_record (store.filename, store.bibentry); X X if (_O_rem) X { X DASSERT (mytmpfile); X (void) restore_bakfile (_O_file, mytmpfile); X } X return 0; X} X X Xonerror_cleanup (rdfd) Xint rdfd; X X{ XFILE *rdfp, *fdopen(); Xchar buffer[100]; X X if (mytmpfile) X { X rdfp = fdopen (rdfd, "r"); X while (fgets (buffer, sizeof(buffer), rdfp)) X Fprintf (mytmpfile, buffer); X (void) restore_bakfile (_O_file, mytmpfile); X } X X return 0; X} X X Xprocess_record (file, string) Xchar *file, *string; X X{ Xint retcode = 0; Xchar tmpfn[20]; X X if (_O_file != file) X { X if (_O_rem) X { X (void) restore_bakfile (_O_file, mytmpfile); X Sprintf (tmpfn, "%s.bak", file); X mytmpfile = fopen (tmpfn, "w"); X } X _O_file = file; X } X X if (REGMATCH (regprog, string) != 1) X { X STASH (string); X retcode = 0; X } X else switch (_O_srch) X { X case FIRST_MATCH: X if (output_record (_O_file, string) == -1) X break /* record was not processed...return normally */; X retcode = -1; X break; X case LAST_MATCH: X if (store.isfull) X { X STASH (store.bibentry); X free (store.bibentry); X } X store.isfull = TRUE; X store.filename = _O_file; X store.bibentry = (char *) replstr (string); X break; X case GLOBAL_MATCH: X (void) output_record (_O_file, string); X break; X } X return retcode; X} X X Xprocess_args (argc, argv) Xint argc; Xchar *argv[]; X X{ Xint opt, count, i; Xextern char *optarg; Xextern int optind; Xchar **temp; X X if (argc <= 1) X _O_help = TRUE; X X while ((opt = getopt (argc, argv, "fghilrs")) != EOF) X switch (opt) { X case 'f': X _O_srch = FIRST_MATCH; X break; X case 'g': X _O_srch = GLOBAL_MATCH; X break; X case 'l': X _O_srch = LAST_MATCH; X break; X case 'h': X _O_help = TRUE; X break; X case 'r': X#ifndef RMBIB X _O_rem = TRUE; X#endif X break; X case 'i': X#ifdef RMBIB X _O_inq = TRUE; X#endif X break; X case 's': X _O_silent = TRUE; X break; X case '?': X default: X _O_help = TRUE; X } X X if (_O_help) X { X (void) usage (); X return -1; X } X X#ifdef RMBIB X _O_rem = TRUE; X#endif X X _O_regexp = argv[optind]; X _O_files = (char **) malloc ((unsigned) (sizeof(char *) * (argc - optind + 1))); X if (_O_files == (char **) NULL) X { X perror (PROGSTR); X exit (-2); X } X X count = 0; X temp = _O_flist = _O_files; X for (i = ++optind; i < argc; i++) X { X *temp = argv[i]; X temp++; X count++; X } X *temp = (char *) NULL; X if (! *_O_flist) X *_O_flist = "-" /* stdin */; X if (count <= 1) _O_silent = TRUE; X store.isfull = FALSE; X X return 0; X} X X Xrestore_bakfile (file, fptr) Xchar *file; XFILE *fptr; X X{ Xchar tmpfn[20]; X X if (! fptr) X return 0; X X fclose (fptr); X Sprintf (tmpfn, "%s.bak", file); X (void) rename (tmpfn, file); X return 0; X} X X Xusage () X X{ X#ifndef RMBIB XFprintf (stderr, "usage: %s [-f] [-l] [-g] [-r] [-s] [-h] reg-expn file(s)\n", X PROGSTR); XFprintf (stderr, "\t-f\tGet first match only\n"); XFprintf (stderr, "\t-l\tGet last matching record only\n"); XFprintf (stderr, "\t-g\tGet all matches\n"); XFprintf (stderr, "\t-r\tDelete matching record\n"); XFprintf (stderr, "\t-s\tAct Silently, ie don't echo record to stdout\n"); XFprintf (stderr, "\t-h\tPrint this help\n"); X#else XFprintf (stderr, "usage: %s [-f] [-l] [-g] [-i] [-s] [-h] reg-expn file(s)\n", X PROGSTR); XFprintf (stderr, "\t-f\tDelete first matching record only\n"); XFprintf (stderr, "\t-l\tDelete last matching record only\n"); XFprintf (stderr, "\t-g\tDelete all matches\n"); XFprintf (stderr, "\t-i\tInquire before deleting record\n"); XFprintf (stderr, "\t-s\tAct Silently, ie don't echo record to stdout\n"); XFprintf (stderr, "\t-h\tPrint this help\n"); X#endif Xreturn 0; X} X X Xoutput_record (file, record) Xchar *file, *record; X X{ X if (! _O_silent) X Fprintf (stdout, "%s:\n", file); X#ifdef RMBIB X if (_O_inq) X { X Fprintf (stderr, "%s\n", record); X if (answer ("remove? ", NO)) X { X STASH (record); X return -1 /* deletion did not occur */; X } X else X Fprintf (stdout, "%s\n", record); X } X#else X Fprintf (stdout, "%s\n", record); X#endif X return 0; X} EOFile bibcent.c chmod u=rw+,g=r++,o=r++ bibcent.c echo '...done' 1>&2 if [ ! -d . ] ; then echo -n Directory . not found. Creating.... mkdir . if [ ! -d . ] ; then echo ...failed echo unable to create directory .. Please create the directory and try again exit fi echo ...done fi echo -n "bibcent.h..." 1>&2 if test -f bibcent.h then case $# in 0) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac case $1 in -o) ;; *) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac fi sed 's/^X//' << 'EOFile bibcent.h' > bibcent.h X/* X * This program has been written by Kannan Varadhan. You are welcome to X * use, copy, modify, or circulate as you please, provided you do not X * charge any fee for any of it, and you do not remove these header X * comments from any of these files. X * X * -- kva Mon Dec 4 11:26:37 EST 1989 X */ X X#include "includes.h" X X#define FIRST_MATCH 1 /* -f flag, the default */ X#define GLOBAL_MATCH 2 /* -g flag */ X#define LAST_MATCH 4 /* -l flag */ X XREGEXP *REGCOMP(); X Xtypedef struct recd { X int isfull; X char *filename; X char *bibentry; X } record; X XDCL (char, _O_srch, FIRST_MATCH); XDCL (char, _O_rem, FALSE); /* -r flag, shent only */ X#ifdef RMBIB XDCL (char, _O_inq, FALSE); /* -i flag, rment only */ X#endif XDCL (char, _O_silent, FALSE); /* -s flag, shent only */ XDCL (char, _O_help, FALSE); /* -h flag */ X XDCLX (char, **_O_files); XDCLX (char, **_O_flist); XDCL (char , *_O_file, (char *) NULL); XDCL (char, *_O_regexp, (char *) NULL); X XDCLX (REGEXP, *regprog); XDCLX (FILE, *mytmpfile); X XDCLX (record, store); X X#ifdef RMBIB X#define STASH(str) fprintf (mytmpfile, "%s\n", str) X#else X#define STASH(str) if (mytmpfile) fprintf (mytmpfile, "%s\n", str) X#endif EOFile bibcent.h chmod u=rw+,g=r++,o=r++ bibcent.h echo '...done' 1>&2 if [ ! -d . ] ; then echo -n Directory . not found. Creating.... mkdir . if [ ! -d . ] ; then echo ...failed echo unable to create directory .. Please create the directory and try again exit fi echo ...done fi echo -n "bibl.l..." 1>&2 if test -f bibl.l then case $# in 0) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac case $1 in -o) ;; *) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac fi sed 's/^X//' << 'EOFile bibl.l' > bibl.l X%{ X X/* X * This program has been written by Kannan Varadhan. You are welcome to X * use, copy, modify, or circulate as you please, provided you do not X * charge any fee for any of it, and you do not remove these header X * comments from any of these files. X * X * -- kva Mon Dec 4 11:26:37 EST 1989 X */ X X#include "bibc.h" X#undef YY_INPUT X#define YY_INPUT(buf,reslt,msize) my_input (buf, &reslt, msize) X Xmy_input (buf,reslt, size) Xchar *buf; Xint *reslt; Xint size; X X{ Xchar inputln[80]; X X bzero (inputln, 80); X if (! GETS (inputln, 80)) X Strcpy (buf, "EOF"); X else X Strncpy (buf, inputln, size); X Strcat (buf, "!"); X#ifdef FLEX_DEBUG X Fprintf (stderr, "buf contains: %s\n", buf); X#endif X return *reslt = strlen (buf); X} X X Xmy_yylex () X X{ X#define PROMPTSTR "\ XWhat kind of record would you like to enter (one of the following)?\n\ X article book booklet conference\n\ X inbook incollection inproceedings manual\n\ X mastersthesis msthesis misc phdthesis\n\ X proceedings techreport unpublished\n\ Xor EDIT quit\n" X X Fprintf (stderr, PROMPTSTR); X return yylex (); X} X X%} X X%% X"a!" return ARTICLE; X"ar!" return ARTICLE; X"art!" return ARTICLE; X"arti!" return ARTICLE; X"artic!" return ARTICLE; X"articl!" return ARTICLE; X"article!" return ARTICLE; X"book!" return BOOK; X"bookl!" return BOOKLET; X"bookle!" return BOOKLET; X"booklet!" return BOOKLET; X"c!" return CONFERENCE; X"co!" return CONFERENCE; X"con!" return CONFERENCE; X"conf!" return CONFERENCE; X"confe!" return CONFERENCE; X"confer!" return CONFERENCE; X"confere!" return CONFERENCE; X"conferen!" return CONFERENCE; X"conferenc!" return CONFERENCE; X"conference!" return CONFERENCE; X"inb!" return INBOOK; X"inbo!" return INBOOK; X"inboo!" return INBOOK; X"inbook!" return INBOOK; X"inc!" return INCOLLECTION; X"inco!" return INCOLLECTION; X"incol!" return INCOLLECTION; X"incoll!" return INCOLLECTION; X"incolle!" return INCOLLECTION; X"incollec!" return INCOLLECTION; X"incollect!" return INCOLLECTION; X"incollecti!" return INCOLLECTION; X"incollectio!" return INCOLLECTION; X"incollection!" return INCOLLECTION; X"inp!" return INPROCEEDINGS; X"inpr!" return INPROCEEDINGS; X"inpro!" return INPROCEEDINGS; X"inproc!" return INPROCEEDINGS; X"inproce!" return INPROCEEDINGS; X"inprocee!" return INPROCEEDINGS; X"inproceed!" return INPROCEEDINGS; X"inproceedi!" return INPROCEEDINGS; X"inproceedin!" return INPROCEEDINGS; X"inproceeding!" return INPROCEEDINGS; X"inproceedings!" return INPROCEEDINGS; X"man!" return MANUAL; X"manu!" return MANUAL; X"manua!" return MANUAL; X"manual!" return MANUAL; X"mas!" return MASTERSTHESIS; X"mast!" return MASTERSTHESIS; X"maste!" return MASTERSTHESIS; X"master!" return MASTERSTHESIS; X"masters!" return MASTERSTHESIS; X"masterst!" return MASTERSTHESIS; X"mastersth!" return MASTERSTHESIS; X"mastersthe!" return MASTERSTHESIS; X"mastersthes!" return MASTERSTHESIS; X"mastersthesi!" return MASTERSTHESIS; X"mastersthesis!" return MASTERSTHESIS; X"ms!" return MASTERSTHESIS; X"mst!" return MASTERSTHESIS; X"msth!" return MASTERSTHESIS; X"msthe!" return MASTERSTHESIS; X"msthes!" return MASTERSTHESIS; X"msthesi!" return MASTERSTHESIS; X"msthesis!" return MASTERSTHESIS; X"mi!" return MISC; X"mis!" return MISC; X"misc!" return MISC; X"ph!" return PHDTHESIS; X"phd!" return PHDTHESIS; X"phdt!" return PHDTHESIS; X"phdth!" return PHDTHESIS; X"phdthe!" return PHDTHESIS; X"phdthes!" return PHDTHESIS; X"phdthesi!" return PHDTHESIS; X"phdthesis!" return PHDTHESIS; X"pr!" return PROCEEDINGS; X"pro!" return PROCEEDINGS; X"proc!" return PROCEEDINGS; X"proce!" return PROCEEDINGS; X"procee!" return PROCEEDINGS; X"procees!" return PROCEEDINGS; X"proceesi!" return PROCEEDINGS; X"proceesin!" return PROCEEDINGS; X"proceesing!" return PROCEEDINGS; X"proceesings!" return PROCEEDINGS; X"t!" return TECHREPORT; X"te!" return TECHREPORT; X"tec!" return TECHREPORT; X"tech!" return TECHREPORT; X"techr!" return TECHREPORT; X"techre!" return TECHREPORT; X"techrep!" return TECHREPORT; X"techrepo!" return TECHREPORT; X"techrepor!" return TECHREPORT; X"techreport!" return TECHREPORT; X"u!" return UNPUBLISHED; X"un!" return UNPUBLISHED; X"unp!" return UNPUBLISHED; X"unpu!" return UNPUBLISHED; X"unpub!" return UNPUBLISHED; X"unpubl!" return UNPUBLISHED; X"unpubli!" return UNPUBLISHED; X"unpublis!" return UNPUBLISHED; X"unpublish!" return UNPUBLISHED; X"unpublishe!" return UNPUBLISHED; X"unpublished!" return UNPUBLISHED; X"quit!" return FLD_NULL; X"EOF!" return FLD_NULL; X"EDIT!" return FLD_EDITOR; X[a-zA-Z0-9]*! return FLD_ERROR; X%% X EOFile bibl.l chmod u=rw+,g=r++,o=r++ bibl.l echo '...done' 1>&2 if [ ! -d . ] ; then echo -n Directory . not found. Creating.... mkdir . if [ ! -d . ] ; then echo ...failed echo unable to create directory .. Please create the directory and try again exit fi echo ...done fi echo -n "bibtools.man..." 1>&2 if test -f bibtools.man then case $# in 0) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac case $1 in -o) ;; *) echo 'exists, `sh filename -o'\'' to overwrite' exit 0;; esac fi sed 's/^X//' << 'EOFile bibtools.man' > bibtools.man X.\" @(#)bibtools.1 (beta version) Sept 15 89 X.TH BIBTOOLS 1 "15 September 1989" X.SH NAME X.sp1 X.nf X\fBbibtools\fP X \fBbibc\fP \- Create BibTeX and scribe style bibliographies X \fBbibv\fP \- Verify a series of BibTeX style bibliographies for X citation conflicts X \fBshbib\fP \- Display one or more records fromthe specified bib files X \fBrmbib\fP \- Delete one or more records fromthe specified bib files X.fi X.SH SYNOPSIS X.sp1 X.nf X\fBbibc\fP [-verify|-i] [-|+pester] [-|+verbose] [-file \fIfilename\fP] [-help] X\fBbibv\fP [-s