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.