ftp.nice.ch/pub/next/text/framemaker/fmbib.1.3.s.tar.gz#/fmbib.c

This is fmbib.c in view mode; [Download] [Up]

/* fmbib.c
 * cm, 17 Dec 90
 * 
 * main module to filter FrameMaker Mif file[s] w/ possible
 * 'Bibliography' markers, and create a new FrameMaker bibliography doc. 
 * 
 * cm, 16 apr 91: 	add bibliography database verification functionality,
 *					when this program is called as 'fmbibverify'.
 * 28 May 92, neek: add bibdirs[] for @include relative filename support.
 */

/*
 * Copyright (c) 1991 Carnegie Mellon University
 * All Rights Reserved.
 * 
 * Permission to use, copy, modify and distribute this software and its
 * documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 *
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * Carnegie Mellon requests users of this software to return to
 *
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 * any improvements or extensions that they make and grant Carnegie Mellon
 * the rights to redistribute these changes.
 */
/* see mif.h */
#define MAIN

#include <stdio.h>
#include <errno.h>
#include <mif.h>
#include <version.h>

extern char *rindex();

char *bibfiles[MAX_BIBFILES];	/* pathnames of bib files - BibFiles var. */
char *bibdirs[MAX_BIBFILES];	/* dirnames bib files - BibFiles var. */
char *bibstyle;	/* Bibliograpy format specified by BibStyle or -s option */


main(ac, av)
	char **av;
{
	char **cp;
	char *bibfile = NULL;
	char *mifbibpath;
	char tmpfile[256];
	register char *ap;
	char *mifpath();
	char *define_bibfile();
	char default_bib=1;
	int n=0;

	if(( prog = rindex(av[0], '/')) == NULL )
		prog = av[0];
	else
		prog++;

	if( strcmp( prog, "fmbibverify" ) == 0)
		verify++;

	bib_markertype = MIF_BIBMARKERTYPE;
	fmbibdir = FMCONTRIBDIR;

	if( !verify )
		err( WARN, "Version %d.%d\n", FMB_VER, FMB_REV );
	else
		err( WARN, "Version %d.%d\n",
			 FMBVERIFY_VER, FMBVERIFY_REV );

	for( cp=av+1; *cp; )
	{
		if( **cp != '-' ) 
		{
			cp++;
			continue;
		}
		ap = (*cp) + 1;
		switch( *ap ) 
		{	
			case 'd':
				debug++;	
				verbose++;
				meltargs(&ac, cp); 
				break;

			case 'a':	/* custom sort keys to be specified as
						 * comma-separated list.
						 */
				if( *(ap+1) )
					custom_sort = ap+1;
				else
				{
					meltargs(&ac, cp);
					if( !*cp )
						err( FATAL, "-a arg needs value\n" );
					custom_sort = *cp;
				}
				meltargs(&ac, cp); 
				break;

			case 'c':
				/* adjacent citations should be comma
				 * separated.
				 */
				if( verify )
				{
					err(WARN, "-c, Unknown switch" );
					usage();
				}
				contiguous_cites++;
				meltargs(&ac, cp); 
				break;
	
			case 'h':
				usage();	/*help*/
				break;

			case 'v':
				verbose++;	
				meltargs(&ac, cp); 
				break;

			case 'm':  /* user-specified bib_markertype value */
				if( verify )
				{
					err(WARN, "-m, Unknown switch" );
					usage();
				}
				if( *(ap+1) )
					bib_markertype = atoi(*(ap+1));
				else
				{
					meltargs(&ac, cp);
					if( !*cp )
						err( FATAL, "-m arg needs value\n" );
					bib_markertype = atoi(*cp);
				}
				meltargs(&ac, cp); 
				break;
			
			case 's':	/* bib format name - overides BibStyle var. */
				if( *(ap+1) )
					bibstyle = ap+1;
				else
				{
					meltargs(&ac, cp);
					if( !*cp )
						err( FATAL, "-f arg needs value\n" );
					bibstyle = *cp;
				}
				meltargs(&ac, cp); 
				break;

			case 'o':	/* output generated bibliography filename */
				if( *(ap+1) )
					bibfile = ap+1;
				else
				{
					meltargs(&ac, cp);
					if( !*cp )
						err( FATAL, "-o arg needs value\n" );
					bibfile = *cp;
				}
				meltargs(&ac, cp); 
				default_bib = 0;
				break;

			case 'r':	/* supply alt. data directory. */
				if( *(ap+1) )
					fmbibdir = ap+1;
				else
				{
					meltargs(&ac, cp);
					if( !*cp )
						err( FATAL, "-r arg needs value\n" );
					fmbibdir = *cp;
				}
				meltargs(&ac, cp); 
				break;

			case 'q':	/* fmbibverify only - query general style info */
				if( verify )
				{
					query++;
					meltargs(&ac, cp);
					break;
				}	
				/* fall through if 'fmbib' */

			default:
				err( WARN,"Unkown switch \"%s\"\n", ap );
				usage();
		}
	}
		
	if( ac < 2  )
		if( !query )
			usage();
	av++;

	/* open output bibliOgraphy file
	 * put it in the same directory as the first
 	 * mif file specified.
	 */
	if( !verify || bibfile )
	{
		if( !bibfile )
			bibfile = define_bibfile( *av, FMDEFAULTBIBLIOGRAPHY );
		mif_open_output( O_BIB, bibfile );
	} 

	/* initialize some data structs. */
	bib_init();

	mifbibpath = mifpath( default_bib ? FMDEFAULTBIBLIOGRAPHY : bibfile );

	if( verify )
		init_bibstyle( bibstyle );

	while( *av )
	{
		if( !verify )
		{
		   /* open document file which will be the
		 	* contents of the current mif doc +
		 	* bibliography cross-references inserted 
		 	*/
			sprintf( tmpfile, "%s.NEW", *av);
			mif_open_output( O_TMP, tmpfile );

			if( verbose )
				err(WARN, "Processing %s\n", *av );
			if( ! mif_open( F_MIF, *av ))
				exit(1);
			mif_parse(mifbibpath);
			mif_close(F_MIF);
			mif_close_output( O_TMP );
			if( verbose )
				err( WARN, "Re-writing %s\n", *av );
			move_file(*av, tmpfile );
		}
		else	/* input files should be bib database files */
		{
			bibfiles[n] = *av;
			n++;
		}
		av++;
	}

	/* the bibfiles[] array should contain at least one bibliography
	 * database file to use. 
	 */
	if( !bibfiles[0] && !query)
		err( FATAL, "No <BibFiles> Variables found in any documents\n" );
	
	if(!ref_parse())
		exit(1);

	if( query )
	{
		print_style_info();
		exit(0);
	}

	/* open/read/parse bibliography database file[s],
	 * and read in only those entries which the user has
	 * cited in their Frame doc.
	 */
	if( !query )
	    if(!bib_parse())
		exit(1);

	if( verify  && !bibfile )
		exit(0);

	/* close output files */
	mif_close_output( O_BIB );

	/* generate the bibliography document. */
	fmbibgen();

	/* consistency check betw. bib markers found, and
	 * associated bibliography data. 
	 */
	chk_bibs();

	if( default_bib || verbose )
		err( WARN, "Generated %s\n", bibfile );

	exit(0);
}


meltargs( ac, av )
	int	*ac;
	char 	**av;
{
	register char **pp;

	for( pp=av; *pp; pp++ )	
		*pp = *(pp+1);
	*pp=0;
	(*ac)--;
}

static char *
define_bibfile( mif_file, default_name)
	char *mif_file;
	char *default_name;
{
	register char *cp;
	static char buf[256];

	strcpy( buf, mif_file );

	if(( cp = rindex(buf, '/' )) == 0)
	{
		strcpy( buf, "./");
		strcat( buf, default_name );
	}
	else
	{
		cp++;
		strcpy( cp, default_name );
	}
	return( buf );
} 


/* build a mif-style device independant absolute pathname
 * to the xref bibliography doc. If this is not absolute,
 * then update xref from within framemaker will only look 
 * in the same directory which the document itself lives in.
 */
static char *
mifpath( unixpath )
	char *unixpath;
{
	register char *sp;
	register char *dp;
	static char buf[256];

	if( !unixpath )
		return( NULL );
	
	dp = buf;

	if( *unixpath == '/' )
	{	
		sp=unixpath;
		strcpy( buf, "<r\\>" );
	}
	else
	{
		strcpy( buf, "<c\\>" );
		/* don't write relative directories, or
		 * Update Cross-references will get confused.
		 * the bib doc will be put into the relative
		 * directory, however this specification should
		 * be just the filename.
		 */
		if((sp = rindex( unixpath, '/' )) == NULL )
			sp = unixpath;
		else
			sp++;
	}
	dp += 4;
		
	for( ; *sp; sp++ )
	{
		if( *sp == '/' )
		{
			strcpy(dp, "<c\\>");
			dp += 4;
		}
		else
			*dp++ = *sp;
	}
	return( buf );
}


print_style_info()
{
	print_valid_pubtypes();
	print_valid_fields();
	print_valid_styles();
	print_refent_defs();
}
	

static char errbuf[1024];

err( severity, fmt, a, b, c, d, e, f)
	int	severity;
	char	*fmt;
	int	a, b, c, d, e, f;
{
	static char	progbuf[40];	

	if( !progbuf[0] )
		sprintf( progbuf, "%s: ", prog);		
	write(2, progbuf, strlen( progbuf ));
	sprintf( errbuf, fmt, a, b, c, d, e, f );
	write( 2, errbuf, strlen(errbuf));
	if( severity == FATAL )
		exit( 1 );
}
	

usage()
{
	register char **cpp;
	static char *options[] = {
		"options:\n",
		"\t-h                      print this help screen.\n",
		"\t-v                      print verbose messages while executing.\n", 
		"\t-c                      contiguous citations should be comma separated\n",
		"\t                        ie, [1,2,3]. Default would be [1][2][3].\n",
		"\t-b                      runs the cover script in 'batch' mode.\n",
		"\t                        This assumes input docs are in Binary Format\n",
		"\t                        Batch mode is OFF by default.\n",
		"\t-o <bibliography file>  generated bibliography file name.\n",
		"\t                        Default is ",
		FMDEFAULTBIBLIOGRAPHY,
		"\n",
		"\t-s <bibliography style> ie, cacm, apa, stdnum, stdident, stdalpha\n",
		"\t                        This overrides the BibStyle Frame variable if set.\n",
		"\t                        Default is stdnum.\n",
		"\t-m <bibmarker number>   re-define which Marker is the Bibliography Marker\n", 
		"\t                        Default is 10.\n",	
		"\t-r <template directory> where templates(.tmpl)/style(.style) files are.\n",
		"\t                        Default is ",
		FMCONTRIBDIR,
		"\n",
		"\t-a <list-sort-fields>   use this switch to customize how\n",
		"\t                        your bibliography document is sorted.\n",
		"\t                        You may specify up to 10 valid sort fields\n",
		"\t                        in a comma-separated list.\n",
		"\t                        Default order is:\n",
		"\t                           key,author,fullauthor,title,journal,\n",
		"\t                           publisher,editor,editors,institution,\n",
		"\t                           organization.\n",
		0,
	};
	static char *voptions[] = {
		"options:\n",
		"\t-h                      print this help screen.\n",
		"\t-s <bibliography style> ie, cacm, ieee, apa, stdnum, stdident, stdalpha\n",
		"\t                        Default is stdnum.\n",
		"\t-r <template directory> where templates(.tmpl)/style(.style) files are.\n",
		"\t                        Default is ",
		FMCONTRIBDIR,
		"\n",
		"\t-o <bibliography file>  generated bibliography file name. If not\n",
		"\t                        specified, no bib. will be generated.\n",
		"\t-q                      query for general syntax and format info\n",
		"\t                        for bib files, as well as mandatory and\n",
		"\t                        optional fields for the current style.\n",
		"\t-a <list-sort-fields>   use this switch to customize how\n",
		"\t                        your bibliography document is sorted.\n",
		"\t                        You may specify up to 10 valid sort fields\n",
		"\t                        in a comma-separated list.\n",
		"\t                        Default order is:\n",
		"\t                           key,author,fullauthor,title,journal,\n",
		"\t                           publisher,editor,editors,institution,\n",
		"\t                           organization.\n",
		0,
	};
	
	if( verify )
		fprintf( stderr, "Usage: %s [options] bib_dbase_file[s]\n",
			prog );
	else
		fprintf( stderr,"Usage: %s [options] mif-file[s]\n",
				prog );

	for( cpp=verify?voptions:options; *cpp; cpp++ )
		fprintf( stderr, *cpp );
	exit(1);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.