#include #include #define MAX 255 #define AND "och" #define ED "red." #define TR "Ă–vers." void field(char *); void entry(void); int pf(char *, ...); char *name; struct entry { int a; /* Number of authors. */ char au[MAX][MAX]; char al[MAX]; char bo[MAX]; char ci[MAX]; char da[MAX]; char ed[MAX]; char jo[MAX]; char no[MAX]; char pg[MAX]; char pu[MAX]; char se[MAX]; char ti[MAX]; char tr[MAX]; char vo[MAX]; char QQ[MAX]; } e; %s ENTRY %% ^%.*\n field(yytext); BEGIN(ENTRY); ^[^%] entry(); ECHO; BEGIN(0); <> entry(); yyterminate(); %% void main(int argc, char *argv[0]) { name = argv[0]; e.a = 0; yylex(); } /* Save entry field. */ void field(char *t) { #define AS(a,b) if(strncmp(t, a, 2) == 0 && (t += 3)){ strcpy(b, t); return; } t++; t[strcspn(t, "\n")] = 0; AS("au",e.au[e.a++]); AS("al",e.al); AS("bo",e.bo); AS("ci",e.ci); AS("da",e.da); AS("ed",e.ed); AS("jo",e.jo); AS("no",e.no); AS("pg",e.pg); AS("pu",e.pu); AS("se",e.se); AS("ti",e.ti); AS("tr",e.tr); AS("vo",e.vo); AS("??",e.QQ); fprintf(stderr, "%s: unrecognized field %%%.2s\n", name, t); exit(1); } /* Print formatted entry. */ void entry() { int i; #define EI(a, b) a ? a : b /* Print authors. */ for(i = 0; i < e.a-2; i++) printf("%s, ", e.au[i]); if(i == e.a-2) printf("%s "AND" ", e.au[i++]); if(i == e.a-1) printf("%s", e.au[i]); (pf(" (%).\n", e.da) || (e.a ? pf(".\n") : 0)); if (*e.bo || *e.jo){ pf("%.\n", e.ti); pf("\\fI%\\fP", EI(e.bo, e.jo)); pf(" ("ED" %)", e.ed); pf(".\n"); }else pf("\\fI%\\fP.\n", e.ti); pf(TR" %.\n", e.tr); (pf("%: %.\n", e.ci, e.pu) || pf("%.\n", e.pu)); #define CL(a) *a = 0 e.a = 0; CL(e.al); CL(e.bo); CL(e.ci); CL(e.da); CL(e.ed); CL(e.jo); CL(e.no); CL(e.pg); CL(e.pu); CL(e.se); CL(e.ti); CL(e.tr); CL(e.vo); CL(e.QQ); } /* Print formatted text if given strings are non-empty. */ int pf(char *fmt, ...) { char *buf, *p; int n; va_list ap; n = 0; for(p = fmt; *p; p++) if(*p == '%') n++; if(!(buf = malloc(strlen(fmt)+n*MAX+1))) err(1, "malloc"); va_start(ap, fmt); for(; *fmt; fmt++) switch(*fmt){ case '%': p = va_arg(ap, char *); if(!p || !*p) return 0; strcat(buf, p); break; default: strncat(buf, fmt, 1); } printf("%s", buf); va_end(ap); return 1; }