This is ref.c in view mode; [Download] [Up]
/* ref.c
* cm, 10 jan 90
* Frame bibliography module which reads in the
* desired bibliography style definition file, parses it into
* execution trees, and the functions to execute the tree when parsing the
* actual bibliography to produce mif output from the bib data found.
*/
/*
* 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.
*/
#include <stdio.h>
#include <ctype.h>
#include <sys/file.h>
#include <mif.h>
#include <bib.h>
#include <ref.h>
#define True 1
#define False 0
/* note: the following States should correspond to
* their indeces into the funcs[] table below
*/
#define R_END -1
#define R_BEGIN 0
#define R_GETREC 1
#define R_GETRECBODY 2
#define R_GETFIELD 3
#define R_GETFIELDVAL 4
#define R_GETFIELDSEP 5
#define R_ENDFIELD 6
#define R_ENDREC 7
#define R_GETDEFINE 8
#define R_GETMANDATORY 9
#define R_GETOPTIONAL 10
/* field flow control tokens */
#define C_IF 1 /* @if */
#define C_ELSE 2 /* @else */
#define C_ELIF 3 /* @elif */
#define C_ENDIF 4 /* @endif */
#define C_CMD 5 /* @i, @b, @n, etc */
#define C_NONE 6 /* illegal syntax */
#define R_OPENPAREN '('
#define R_CLOSEPAREN ')'
extern char *reftypes[];
extern char *bibstyle;
extern int new_para;
int f_getdefine();
static int r_begin(), r_getrec(), r_getrecbody(),
r_getfield(), r_getfieldval(), r_getfieldsep(),
r_endfield(), r_endrec(), r_getdefine(), r_getmandatory(),
r_getoptional();
static int (*funcs[])() =
{
r_begin,
r_getrec,
r_getrecbody,
r_getfield,
r_getfieldval,
r_getfieldsep,
r_endfield,
r_endrec,
r_getdefine,
r_getmandatory,
r_getoptional,
};
/* execution tree routines */
int rf_test(); /* test whether specified field present in bib ent */
int rf_prtfield(); /* output the contents of the specified bib field */
int rf_prtlit(); /* output the specified literal chars. */
int rf_chfont(); /* output change font command. */
int rf_newline(); /* output line break */
int rf_true(); /* pass-thru function, always true */
/* static globals */
static RefEnt *rep; /* -> current reference style */
static ExecEnt *exroot; /* current head of field exec tree */
static char *lp; /* current place in current input line */
static char token[1024]; /* build current token here. */
static char buf[1024];
static char pgfstarted;
char *font_statement();
/* return 1 on success, 0 on failure
*/
ref_parse()
{
register int state;
char name[256];
char orig[256];
sprintf( name, "%s/%s.style", fmbibdir, bibstyle );
strcpy( orig, name );
if( access(name, R_OK ) == -1 )
{
sprintf(name, "%s/%s.style", FMCONTRIBDIR, bibstyle);
if( access( name, R_OK ) == -1 )
{
sprintf(name, "%s/%s", fmbibdir, FMBIBSTYLEFILE );
if( access( name, R_OK ) == -1 )
{
sprintf(name, "%s/%s", FMCONTRIBDIR, FMBIBSTYLEFILE );
if( access( name, R_OK ) == -1 )
err(FATAL, "Can't find usable %s file.\n",
name );
}
}
}
if( ! mif_open( F_REF, name ))
err( FATAL, "Can't open %s.\n", name );
else if( strcmp( name, orig ))
err( WARN, "Using %s as MIF style file.\n", name );
state = R_BEGIN;
while( state != R_END )
{
state = funcs[state]();
}
mif_close( F_REF );
return(1);
}
/* get next token from file
* return NULL at end of file.
* if 'delim' is non-zero, it points to a char.
* to use as the end delimeter of the current token, else
* use the default (spaces and refdelimeters)
*/
static char *
ref_gettok(delim)
register char *delim;
{
register char c;
register char *cp, *tp;
tp = token;
while(1)
{
if( ! (cp = mif_getc(F_REF)) )
if( tp == token )
return( NULL ); /* eof */
else
break;
c = *cp;
if( delim )
{
if(c == *delim )
{
if( tp == token )
return( NULL );
mif_ungetc(F_REF);
break;
}
if( c == '\\' ) /* esc. quote */
{
if( ! (cp = mif_getc(F_REF)) )
return( NULL ); /* eof */
else
{
*tp++ = *cp;
continue;
}
}
}
else
{
/* check for comments, if found, eat to eol */
if( c == '#' )
{
while( cp = mif_getc(F_REF) )
if( ! *cp )
break;
if( tp == token )
{
if( !cp )
return(NULL);
else
continue;
}
break;
}
if( isspace(c) || c == 0)
{
if( tp == token )
continue;
else
break;
}
/* special cases */
if( isrefdelimeter(c) )
{
if( tp != token )
mif_ungetc(F_REF);
else
*tp++ = c;
break;
}
}
*tp++ = c;
}
*tp = 0;
return( token );
}
static
isrefdelimeter(c)
char c;
{
/* refstyle token delimeters */
static char refdelims[] = {
'{', '}', '(', ')', '"', '<', '>', ',', '@', '=', '|', 0,
};
register char *cp;
for(cp=refdelims; *cp; cp++ )
if( *cp == c )
return( *cp );
return( 0 );
}
/*********
* parse/state routines
********/
static
r_begin()
{
return( R_GETREC );
}
static
r_getrec()
{
RefType rtype;
char lcase[256];
while( 1 )
{
lp = ref_gettok(0);
if( !lp )
return (R_END);
if( tokeq(lp, '@') )
{
lp = ref_gettok(0);
if(( rtype = reftype(lp)) >= 0 )
{
rep = new_refent();
rep->re_type = rtype;
return( R_GETRECBODY );
}
else
{ /* @string macros */
strtolower( lcase, lp );
if( streq( lcase, "string" ))
return(R_GETDEFINE);
}
}
}
}
static
r_getrecbody()
{
lp = ref_gettok(0);
if( !lp )
{
err( WARN,"%s: syntax, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return (R_END);
}
if( !tokeq( lp, R_OPENPAREN))
err( WARN,"%s: expecting '{', line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_GETFIELD );
}
static
r_getfield()
{
lp = ref_gettok(0);
if( !lp )
{
err( WARN,"%s: syntax, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_ENDREC );
}
if( tokeq( lp, R_CLOSEPAREN ))
return( R_ENDREC );
/* look for @mandatory or @optional directives */
if( tokeq( lp, '@' ))
{
if( !(lp = ref_gettok(0)))
{
err( WARN,"%s: syntax, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_ENDREC );
}
if( streq( lp, "mandatory" ))
return( R_GETMANDATORY );
else if( streq( lp, "optional" ))
return( R_GETOPTIONAL );
else
{
err( WARN, "%s: illegal field name (%s), line %d\n",
mif_filename(F_REF), lp, mif_lineno(F_REF));
return( R_GETFIELDSEP );
}
}
/* create root of new exectree */
exroot = new_execent();
if( tokeq( lp, '*' )) /* non-field, forces execution on 'true' */
{
exroot->ex_func = rf_true;
exroot->ex_arg = (char *)1;
}
else
{
if((int)(exroot->ex_arg = (char *) fldtype(lp)) < 0 )
{
err( WARN, "%s: illegal field name (%s), line %d\n",
mif_filename(F_REF), lp, mif_lineno(F_REF));
free( exroot );
return( R_GETFIELDSEP );
}
exroot->ex_func = rf_test;
}
return( R_GETFIELDVAL );
}
#define FS_PARSE 0
#define FS_DONE 1
static int depth;
static char fldstate;
static
r_getfieldval()
{
/* start recursive function to parse and insert
* fields into the current exectree.
*/
depth=0;
fldstate = FS_PARSE;
return( do_exectree( exroot, True ));
}
static
do_exectree( exp, tf )
register ExecEnt *exp; /* root of current exectree */
int tf; /* insert as a true or false subtree */
{
register ExecEnt *newp, *np;
short first=True;
register ExecEnt **insertp;
np = exp;
while( 1 )
{
if( fldstate == FS_DONE )
return( R_ENDFIELD);
lp = ref_gettok(0);
if( !lp )
{
err( WARN,"%s: no end of record, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_END );
}
if( tokeq( lp, ',' ))
{
if( depth )
{
err( WARN,"%s: unexpected end of field, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
depth=0;
}
fldstate = FS_DONE;
return( R_ENDFIELD );
}
else if( tokeq( lp, R_CLOSEPAREN ))
{
if( depth )
err( WARN,"%s: unexpected end of field, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_ENDFIELD );
}
/* create new ExecEnt node.*/
newp = new_execent();
if( first ) /* insert under t/f */
{
first = False;
insertp = tf ? &(np->ex_true) : &(np->ex_false);
}
else
insertp = &(np->ex_next);
if( tokeq( lp, '<' )) /* print field contents */
{
lp = ref_gettok(">");
if( !lp )
{
err( WARN,"%s: syntax error, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_END );
}
else
{
newp->ex_func = rf_prtfield;
if( tokeq( lp, '@' ) ) /* print the tested field */
newp->ex_arg = exp->ex_arg;
else if((int)(newp->ex_arg = (char *) fldtype(lp)) < 0 )
{
err( WARN, "%s: illegal field name (%s), line %d\n",
mif_filename(F_REF), lp, mif_lineno(F_REF));
return( R_GETFIELDSEP );
}
*insertp = newp;
np = newp;
}
/* eat '>' */
lp = ref_gettok(0);
}
else if tokeq( lp, '"' ) /* print literal string */
{
lp = ref_gettok("\"");
if( !lp )
{
err( WARN,"%s: syntax error, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_END );
}
else
{
newp->ex_func = rf_prtlit;
newp->ex_arg = getmem( strlen(lp)+1);
strcpy( newp->ex_arg, lp );
*insertp = newp;
np = newp;
}
/* eat '"' */
lp = ref_gettok(0);
}
else if tokeq( lp, '@' ) /* command */
{
lp = ref_gettok(0);
if( !lp )
{
err( WARN,"%s: syntax error, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_END );
}
switch( get_atcmd( newp, lp ) ) {
case C_CMD: /* get_atcmd filled populated newp */
*insertp = newp;
np = newp;
break;
case C_IF:
depth++;
newp->ex_func = rf_test;
if( !(lp = ref_gettok(0)))
{
err( WARN,"%s: syntax error, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_END );
}
if((int)(newp->ex_arg = (char *) fldtype(lp)) < 0 )
{
err( WARN, "%s: illegal field name (%s), line %d\n",
mif_filename(F_REF), lp, mif_lineno(F_REF));
return( R_GETFIELDSEP );
}
*insertp = newp;
np = newp;
/* a new 'if' statement means a new 'True' exec
* sub-tree under the current node.
*/
do_exectree( np, True );
break;
case C_ELIF:
depth++;
newp->ex_func = rf_test;
if( !(lp = ref_gettok(0)))
{
err( WARN,"%s: syntax error, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_END );
}
if((int)(newp->ex_arg = (char *) fldtype(lp)) < 0 )
{
err( WARN, "%s: illegal field name (%s), line %d\n",
mif_filename(F_REF), lp, mif_lineno(F_REF));
return( R_GETFIELDSEP );
}
exp->ex_false = newp;
np = newp;
/* a new 'if' statement means a new 'True' exec
* sub-tree under the current root node.
*/
do_exectree( np, True );
break;
case C_ELSE:
/* a new 'else' statement means a new 'False' exec
* sub-tree under the root of the current subtree.
*/
depth++;
do_exectree(exp, False );
break;
case C_ENDIF:
depth--;
if( depth < 0 )
err( WARN,"%s: @endif missing @if, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
/* doesn't matter value of this return, since
* we should be returning to an inner do_exectree().
*/
return(R_END);
case C_NONE:
err( WARN,"%s: bad @ command, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_GETFIELDSEP );
} /* switch */
}
else /* unknown token */
err( WARN, "%s: illegal syntax (%s), line %d\n",
mif_filename(F_REF), lp, mif_lineno(F_REF));
} /* while */
}
get_atcmd( np, cp )
register ExecEnt *np;
char *cp;
{
register i;
static char atcmds[] = { 'i','r','b','u','n', 0 };
static int (*atfuncs[])() = {
rf_chfont, rf_chfont, rf_chfont, rf_chfont,
rf_newline, 0 };
static int atargs[] = { F_ITALIC, F_REGULAR, F_BOLD,
F_UNDERLINE, 0, 0 };
if( *(cp+1) == 0 )
{
for( i=0; atcmds[i]; i++ )
if( atcmds[i] == *cp )
{
np->ex_func = atfuncs[i];
np->ex_arg = (char *) atargs[i];
return(C_CMD);
}
return(C_NONE);
}
else
{
/* try 'if', 'else', 'endif' control structs. */
if( streq( lp, "if" ))
return( C_IF );
else if( streq( lp, "else" ))
return( C_ELSE );
else if( streq( lp, "elif" ))
return( C_ELIF );
else if( streq( lp, "endif" ))
return( C_ENDIF );
else
return( C_NONE );
}
}
static
r_getfieldsep()
{
while( 1 )
{
if( !(lp = ref_gettok(0)))
{
err( WARN,"%s: no end of record, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_END );
}
if( tokeq(lp, ',') || tokeq( lp, R_CLOSEPAREN) || (*lp == 0))
return( R_ENDFIELD );
}
}
static
r_getmandatory()
{
return( get_fldlist(&rep->re_mandatory));
}
static
r_getoptional()
{
return( get_fldlist(&rep->re_optional));
}
static
get_fldlist(listp)
RefFldList **listp;
{
RefFldList *flp, *altfp;
FldType crrntfld;
if( !(lp = ref_gettok(0)))
{
err( WARN,"%s: no end of record, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_END );
}
if( !tokeq(lp, R_OPENPAREN))
{
err( WARN,"%s: expecting %c, line %d\n",
mif_filename(F_REF), R_OPENPAREN, mif_lineno(F_REF) );
return( R_GETFIELDSEP );
}
*listp = flp = new_fldlist();
while( 1 )
{
if( !(lp = ref_gettok(0)))
{
err( WARN,"%s: no end of record, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_END );
}
if( tokeq( lp, R_CLOSEPAREN ))
return( R_GETFIELD );
if( tokeq( lp, ',' ) )
continue;
if(tokeq( lp, '|' ))
{
REMFLD( flp->fl_flds, crrntfld );
altfp = get_altflds( crrntfld );
insert_altflds( flp, altfp );
continue;
}
if((crrntfld = fldtype(lp)) < 0 )
{
err( WARN, "%s: illegal field name (%s), line %d\n",
mif_filename(F_REF), lp, mif_lineno(F_REF));
continue;
}
ADDFLD( flp->fl_flds, crrntfld );
}
}
static
RefFldList *
get_altflds( firstfld )
FldType firstfld;
{
RefFldList *flp;
FldType crrntfld;
flp = new_fldlist();
ADDFLD( flp->fl_flds, firstfld );
while(1)
{
if( !(lp = ref_gettok(0)))
{
err( WARN,"%s: no end of record, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
break;
}
if( tokeq( lp, ',') || tokeq( lp, R_CLOSEPAREN ))
break;
if(tokeq( lp, '|' ))
continue;
if((crrntfld = fldtype(lp)) < 0 )
{
err( WARN, "%s: illegal field name (%s), line %d\n",
mif_filename(F_REF), lp, mif_lineno(F_REF));
continue;
}
ADDFLD( flp->fl_flds, crrntfld );
}
return( flp );
}
static
r_endfield()
{
/* link this field's exectree into ref type */
store_exectree( rep, exroot );
return( R_GETFIELD );
}
/* store the record just parsed
*/
static
r_endrec()
{
store_refent( rep );
return( R_GETREC );
}
/* read @string macro, include the definition.
* note: these can be read in from either the bibliography database,
* or the .style files. since the bibliography db's are read in first,
* these will take precedence if duplicate keys are found.
*/
static
r_getdefine()
{
register char *lp;
char *endval;
char key[256];
/* get open brace */
lp = ref_gettok(0);
if( !lp )
{
err( WARN,"%s: syntax error, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_GETREC );
}
if( !(endval = get_opp_brace( lp )))
{
err( WARN,"%s: expecting open brace, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_GETREC );
}
while( !tokeq( lp, *endval ))
{
/* get key */
lp = ref_gettok(0);
if( !lp )
{
err( WARN,"%s: syntax error, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_GETREC );
}
strcpy(key, lp );
/* get to string */
while( lp = ref_gettok(0))
{
if( !lp )
{
err( WARN,"%s: syntax error, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_GETREC );
}
if( tokeq( lp, '"' ))
break;
if( tokeq( lp, *endval ))
{
err( WARN,"%s: syntax error, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_GETREC );
}
}
/* get quoted string */
if( !(lp = ref_gettok("\"")))
{
err( WARN,"%s: unterminated quoted string, line %d\n",
mif_filename(F_REF), mif_lineno(F_REF) );
return( R_GETREC );
}
/* store it away. */
store_bibdef( key, lp );
lp = ref_gettok(0); /* close quote */
lp = ref_gettok(0); /* either endval or comma */
}
/* go on with your life. */
return( R_GETREC );
}
/****************
* execution routines to produce bib output
****************
/* test whether this field exists in the current
* bibliography entry. return true/false accordingly.
*/
rf_test( ep, bp )
ExecEnt *ep;
BibEnt *bp;
{
register FldType fld = (FldType)ep->ex_arg;
register long rollcall = bp->be_rollcall;
return( (int) FLDPRESENT(rollcall, fld));
}
/* output the contents of the specified field from
* the bibliography reference.
*/
rf_prtfield( ep, bp)
ExecEnt *ep;
BibEnt *bp;
{
register FldType fld = (FldType)ep->ex_arg;
register long rollcall = bp->be_rollcall;
register BibField *bf;
if( !(bf = find_bibfield( bp, fld))) return(1);
if( new_para )
{
mif_pgfbegin( bp );
new_para = 0;
}
mif_string( O_BIB, bf->bf_val );
return(1);
}
/* output a literal string.
*/
rf_prtlit( ep, bp )
register ExecEnt *ep;
BibEnt *bp;
{
if( new_para )
{
mif_pgfbegin( bp );
new_para = 0;
}
mif_string( O_BIB, ep->ex_arg);
return(1);
}
/* output change font command.
*/
rf_chfont( ep, bp )
register ExecEnt *ep;
BibEnt *bp;
{
if( new_para )
{
mif_pgfbegin( bp );
new_para = 0;
}
if( current_font != (short) ep->ex_arg)
mif_chfont(O_BIB, (short) ep->ex_arg);
return(1);
}
/* output a line break command.
*/
rf_newline( useless, arg )
{
mif_linebreak( O_BIB );
return(1);
}
/* function which is always true */
rf_true( useless, arg )
{
return(1);
}
/*********************
* mif output routines
*********************/
/* output a string as a mif command, replace single quote "'",
* w/ "\'", and open/close double quotes w/ smartquotes.
*/
mif_string( type, str )
int type;
char *str;
{
static short q_left = 1; /* keep track of smart quotes. */
register char *sp, *dp;
static short first=1;
static len;
static char strbuf[1024];
static char lastchar = 0;
if( !str || !*str)
return;
if( first )
{
first=0;
strcpy( strbuf, " <String `");
len = strlen(strbuf);
}
/* don't mistakenly replicate double punctuation marks
* from string to string. For example, if authors field
* ends in a period because his bibligraphy uses intials,
* placing a period after this field will print a double
* period.
*/
if( *str == lastchar )
str++;
for( sp=str, dp = strbuf+len; *sp; sp++, dp++ )
{
if( *sp == '\'' )
*dp++ = '\\';
else if( *sp == '"' )
{
if( q_left )
{
q_left = 0;
strcpy( dp, "\\xd2 " ); /* open */
dp += 4;
}
else
{
q_left = 1;
strcpy( dp, "\\xd3 " ); /* close */
dp += 4;
}
continue;
}
*dp = *sp;
}
for( sp--; isspace(*sp); sp-- )
;
lastchar = *sp;
*dp++ = '\'';
*dp++ = '>';
*dp++ = 0;
mif_writeln( O_BIB, strbuf);
}
/* output a mif change font cmd.
*/
mif_chfont( type, font )
int type;
int font;
{
sprintf( buf, " <Font \n%s > \n",
font_statement( font ));
mif_write( type, buf );
current_font = font;
}
/* output a mif line break.
*/
mif_linebreak( type )
{
/* for now, output space, since frame's doing the formatting.
*/
mif_writeln( type, " <String ` '>");
}
mif_pgfbegin( bep )
BibEnt *bep;
{
mif_write(O_BIB, " <Para \n" );
prt_tag( bep ); /* <PgfTag .... > */
mif_write( O_BIB, " <ParaLine \n" );
sprintf( buf, " <Marker \n <MType 9> \n <MText `%s'> \n > # end of Marker\n",
bep->be_xref);
mif_write(O_BIB, buf );
/* generate the reference string depending on the style */
prt_refstring(bep);
pgfstarted=1;
}
mif_pgfend(bep)
BibEnt *bep;
{
/* it is possible that no fields were found present, and
* that a paragraph has not been started. If so, just return.
*/
if( !pgfstarted )
{
err( WARN, "No valid bid data to write <%s> cross ref\n",
bep->be_xref );
return;
}
mif_write( O_BIB, " > # end of ParaLine\n > # end of Para \n" );
pgfstarted=0;
}
mif_beginbibdoc()
{
char bibtemplate[256];
char orig[256];
char *bib_templatefile();
/* copy the correct template for the format of the doc. */
sprintf(bibtemplate, "%s/%s.tmpl", fmbibdir, bib_templatefile() );
strcpy( orig, bibtemplate );
if( access( bibtemplate, R_OK ) == -1 )
{
sprintf(bibtemplate, "%s/%s.tmpl", FMCONTRIBDIR, bib_templatefile() );
if( access( bibtemplate, R_OK ) == -1 )
{
sprintf(bibtemplate, "%s/%s", fmbibdir, FMBIBTEMPLATEFILE );
if( access( bibtemplate, R_OK ) == -1 )
{
sprintf(bibtemplate, "%s/%s", FMCONTRIBDIR, FMBIBTEMPLATEFILE );
if( access( bibtemplate, R_OK ) == -1 )
err(FATAL, "Can't find usable bib template (%s)\n",
bib_templatefile() );
}
}
}
if( ! copy_bibtemplate( bibtemplate ) )
err(FATAL, "Could not copy <%s> template\n", bibtemplate );
if( strcmp(bibtemplate, orig ))
err( WARN, "Using %s as template file.\n", bibtemplate );
current_font = F_REGULAR;
}
mif_endbibdoc()
{
mif_write( O_BIB, "> #end of TextFlow\n# End of MIFfile\n" );
}
/* execute a single exec tree using the field values from
* the specified bib entry.
*/
exec_tree( root, bep )
ExecEnt *root;
register BibEnt *bep;
{
register ExecEnt *ep;
if( root == NULL )
return;
if(root->ex_func == rf_test)
{
if( rf_test(root, bep) )
ep = root->ex_true;
else
ep = root->ex_false;
}
else if(root->ex_func == rf_true)
{
ep = root->ex_true;
}
else
{
err( WARN,"exec_tree(): corrupted.\n");
return;
}
for( ;ep; ep = ep->ex_next )
{
if(ep->ex_func == rf_test)
exec_tree( ep, bep );
else
ep->ex_func( ep, bep );
}
}
char *
font_statement( n )
{
static char *fontstat[] = {
" <FTag `'>\n <FAngle `Regular'>\n",
" <FTag `Emphasis'>\n <FAngle `Italic'>\n",
" <FTag `Emphasis'>\n <FAngle `Regular'>\n <FWeight `Bold'>\n",
" <FTag `Emphasis'>\n <FAngle `Regular'>\n <FUnderline Yes>\n",
};
return(fontstat[n-1]);
}
#ifdef DEBUG
/************
* debugging..
************/
char *
prt_execent(exp)
register ExecEnt *exp;
{
static char ret[128];
if( exp->ex_func == rf_test )
sprintf(ret,"TEST( %s )", fldname(exp->ex_arg));
else if( exp->ex_func == rf_prtfield )
sprintf(ret,"PRINT_FIELD( %s )", fldname(exp->ex_arg));
else if( exp->ex_func == rf_prtlit )
sprintf(ret,"PRINT_LITERAL( %s )", exp->ex_arg);
else if( exp->ex_func == rf_chfont )
sprintf(ret,"CHANGE_FONT( %s )", fontname(exp->ex_arg));
else if( exp->ex_func == rf_newline )
strcpy( ret, "NEWLINE()");
else if( exp->ex_func == rf_true )
strcpy( ret, "ALWAYS()" );
else
strcpy( ret, "UNKNOWN_FUNC ???" );
return( ret );
}
/* generated mif output. modules.
*/
char *
fontname(n)
{
static char *fonts[] = {
"Regular", "Italic", "Bold", "Underline"
};
return(fonts[n-1]);
}
#endif DEBUG
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.